Angular, cz. I - Instytut Informatyki Teoretycznej i Stosowanej

Transkrypt

Angular, cz. I - Instytut Informatyki Teoretycznej i Stosowanej
Angular, cz. I
Angular, cz. I
Tworzenie serwisów Web 2.0
dr inż. Robert Perliński
[email protected]
Politechnika Częstochowska
Instytut Informatyki Teoretycznej i Stosowanej
14 marca 2016
1/48
Plan prezentacji
1
Framework
2
Angular 1.5
Hello World
Internacjonalizacja i lokalizacja
Wyrażenia
Filtry
Moduły
Kontroler
Dyrektywy
show, hide, repeat, src
click, init, class, model
Kontroler - prosta logika
Formularze
Dyrektywy submit, options
Sprawdzanie poprawności - walidacja
3
Źródła
Angular, cz. I
2/48
Framework I
Framework (platforma programistyczna) - szkielet do budowy
aplikacji.
Definiuje strukturę aplikacji oraz ogólny mechanizm jej działania.
Dostarcza zestaw komponentów i bibliotek.
Tworzenie aplikacji polega na rozbudowie i dostosowaniu
poszczególnych komponentów do wymagań określonego projektu.
Framework to nie biblioteka oprogramowania.
Framework to samodzielna kategoria oprogramowania.
Angular, cz. I
3/48
Framework II
Framework to samodzielna kategoria oprogramowania, świadczą o tym
takie cechy jak:
Odwrócenie sterowania - przepływ sterowania jest narzucony przez
framework, nie przez użytkownika.
Domyślne zachowanie - posiada domyślną konfigurację, która sama w
sobie jest użyteczna i daje sensowny wynik, inaczej niż np. jQuery.
Rozszerzalność - poszczególne komponenty są rozszerzalne przez
programistę na potrzeby dodatkowej funkcjonalności.
Zamknięta struktura wewnętrzna - framework można rozbudowywać
ale nie przez modyfikację domyślnego kodu.
Angular, cz. I
4/48
Framework III
Framework składa się z zamrożonych i gorących punktów.
Zimne punkty definiują ogólną architekturę konkretnego typu
oprogramowania, tj. zestaw podstawowych komponentów i zależności
między nimi.
Ta architektura (zimne punkty), pozostają niezmienne dla danego
frameworku.
Ogólna architektura dla danego frameworku jest taka sama pośród
różnych projektów w nim napisanych.
Gorące punkty reprezentują te części projektu, które programista
rozszerza.
Gorące punktu są osadzone we frameworku a nie na odwrót.
Klasy i komponenty użytkownika otrzymują syngały od frameworka,
który zarządza wykonywaniem aplikacji.
Widać tutaj różnicę w porównaniu do biblioteki oprogramowania.
Angular, cz. I
5/48
Framework IV - wady i zalety
Zalety:
efektywność - programista pisze mniej kodu, bo już bardzo dużo jest
przygotowane,
poprawa jakości kodu - framework ma być elastyczny więc ma dobrze
przemyślaną organizację wewnętrzną i logikę,
niezawodność - jak coś jest dobrze przygotowane i przetestowane, a
takie oczekiwania stawia się szkieletom aplikacji, to nie powinno być
błędów czy większych problemów z działaniem.
Wady:
złożoność - nie łatwo się nauczyć frameworka, bo jest on
przygotowany jako elastyczny i używa wielu zaawansowanych
koncepcji,
wydajność - jak budowa jest elastyczna to często kosztem szybkości
działania.
Angular, cz. I
6/48
AngularJS - wersja 1.5
Strona projektu: https://angularjs.org/
Dokumentacja: https://docs.angularjs.org/api
Tutorial: https://docs.angularjs.org/tutorial
Przewodnik dla developerów: https://docs.angularjs.org/guide
Kurs na CodeSchool: http://angular.codeschool.com/
Angular, cz. I
7/48
Hello World - szablon HTML
index.html
<!DOCTYPE html>
<html ng-app="hello">
<head>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
<p>{{4+6}}</p>
</body>
</html>
app.js
var app = angular.module(’hello’, [ ]);
Angular, cz. I
8/48
Hello World - opis
ng-app - dyrektywa, która tworzy aplikację Angular kiedy strona jest
wczytywana: <html lang="pl" ng-app="hello">
należy też dołączyć bibliotekę Angular:
<script type="text/javascript" src="angular.min.js"></script>
a także plik z utworzonym modułem:
<script type="text/javascript" src="app.js"></script>
w pliku app.js jest definicja modułu, który nic nie robi, ale dołączony
pozwala traktować cały kod wewnątrz elementu, do którego jest
dołączony jako aplikację Angular
var app = angular.module(’hello’, [ ]);
teraz w zakresie zancznika <html> można używać wyrażeń, np.:
{{(3+5*4)/2}} - otrzymamy wartość 11.5
{{’Hello ’+" World"}} - Hello World
Angular, cz. I
9/48
Internacjonalizacja i lokalizacja
internationalization (i18n), localization (l10n):
proces tworzenia produktu w taki sposób, żeby łatwo było dostosować
go do potrzeb języka czy kultury,
trzeba dostarczyć tłumaczenie słów, formatów danych, ... do
lokalnych potrzeb.
Angular wspiera i18n/l10n dla dat, liczb i walut.
ID lokalizacyjne:
id określające region geograficzny, polityczny czy kulturalny,
najczęściej składa się z dwóch części: kod języka-kod kraju,
przykłady: en-US, en-AU, pl-PL, ... ale też: en, pl, sk, ...
Angular, cz. I
10/48
Internacjonalizacja II
Pliki ze skryptami do lokalizacji:
https://github.com/angular/angular.js/tree/master/src/ngLocale
Dwa polskie (niczym się nie różnią):
angular-locale pl.js
angular-locale pl-pl.js
dużo innych ...
Dwa podejścia:
dodanie lokalizacji na stałe do skryptu angular.js:
cat angular.js angular-locale_pl-pl.js > angular_pl-pl.js
dołączenie skryptu z lokalizacją do pliku html:
<html ng-app>
<head>
...
<script src="angular.min.js"></script>
<script src="angular-locale_pl-pl.js"></script>
</head>
</html>
Angular, cz. I
11/48
Obsługa liczby mnogiej - ng-pluralize
Język polski (kod: pl)
Kategoria
jeden (one)
kilka (few)
Przykład
1
2-4, 22-24, 32-34...
wiele (many)
0, 5-21, 25-31, 35-41...
inne (other)
1.2, 2.07, 5.94...
Zasady
n wynosi 1
n mod 10 w granicach 2..4 AND
n mod 100 poza zakresem 12..14;
n różne od 1 AND n mod 10 w zakresie 0..1 OR
n mod 10 w zakresie 5..9 OR n mod 100 w zakresie 12..14
wszystkie inne liczby
Dyrektywa ng-pluralize:
wyświetla informacje zgodnie z odmianą liczebników w danym języku,
należy określić mapowanie między kategoriami liczbeności a
wyświetlanymi napisami,
kategorie liczebności to konkretne liczby albo grupy liczb,
posiada parametr offset, który określa na lepsze sprecyzowanie
wyświetlanego tekstu.
Angular, cz. I
12/48
Przykład ng-pluralize
<label>Liczba kotów:
<input type="text" ng-model="catCount" value="0" /></label><br/>
<div ng-pluralize count="catCount"
when="{’0’
: ’0 kotów, czyli brak :)’,
’one’ : ’1 kot’,
’few’ : ’*2,*3,*4 koty’,
’many’ : ’*5,*6,*7,*8,*9,*0,... kotów’,
’other’: ’{} kotów jest na dachu’}">
</div>
<ng-pluralize count="catCount"
when="{’0’
: ’0 kotów, czyli brak :)’,
’one’ : ’1 kot’,
’few’ : ’*2,*3,*4 koty’,
’many’ : ’*5,*6,*7,*8,*9,*0,... kotów’,
’other’: ’{} kotów jest na dachu’}">
</ng-pluralize><br><br>
Angular, cz. I
13/48
Przykład ng-pluralize
<label>Osoba 1: <input type="text" ng-model="os1" value="" /></label><br/>
<label>Osoba 2: <input type="text" ng-model="os2" value="" /></label><br/>
<label>Liczba osób:
<input type="text" ng-model="personCount" value="1" /></label><br/>
Bez przesunięcia (offset):
<ng-pluralize count="personCount"
when="{’0’
: ’Nikt nie ogląda strony’,
’one’ : ’1 osoba (one) ogląda stronę’,
’few’ : ’{} (few) osoby oglądają stronę’,
’many’ : ’{} (many) osób ogląda stronę’,
’other’: ’Inna liczba (other) osób ({}) ogląda stronę’}">
</ng-pluralize><br>
Z przesunięciem równym 2:
<ng-pluralize count="personCount" offset=2
when="{’0’
: ’Nikt nie ogląda strony’,
’1’
: ’{{os1}} ogląda stronę’,
’2’
: ’{{os1}} i {{os2}} oglądają stronę’,
’one’ : ’{{os1}} i {{os2}} i jeszcze jedna osoba oglądają stronę’,
’few’ : ’{{os1}} i {{os2}} i jeszcze {} inne osoby oglądają stronę’,
’many’: ’{{os1}} i {{os2}} i jeszcze {} innych osób ogląda stronę’
}">
</ng-pluralize>
Angular, cz. I
14/48
Wyrażenia
Wyrażenia pozwalają na wyświetlanie różnych danych na stronie.
{{4+6}} - operacje numeryczne, tutaj dodawanie,
{{"Hello" + " World"}} - Hello World - operacje na napisach,
{{3.1*12|currency}} - $37.20 - operacja numeryczna z filtrem
walutowym (internacjonalizacja),
{{sklep.produkt.opis}} - ’Treść opisu...’ - wyświetla zawartość
pola opis właściwości produkt kontrolera sklep,
{{ zm[index]>2 ? 100 : 0.12 }} - z wyjątkiem operatora ?:
nie można kontrolować przepływu sterowania,
{{::nazwa}} vs {{nazwa}} - :: przed nazwą zmiennej - jednokrotne
wiązanie, po ustalonej wartości takie wyrażenia nie zmienią już swojej
wartości - dla zwiększenia wydajności wtrony.
Angular, cz. I
15/48
Filtry
Filtry:
wykorzystujemy za pośrednictwem symbolu | (jak potoki w linux’ie).
Angular ma kilka filtrów. W widoku wykorzystujemy je w następująco:
// Proste zastosowanie
{{ wyrażenie | filtr }}
// Przetwarzanie potokowe
{{ wyrażenie | filtr1 | filtr2 | ... }}
// Wykorzystanie argumentów (opcji)
{{ wyrażenie | filtr:argument1:argument2:... }}
Można ich używać:
w szablonie widoku, kontrolerach, usługach czy dyrektywach.
Istnieje możliwość definiowania własnych filtrów ($filterProvider).
Angular, cz. I
16/48
Lista filtrów I
currency - filtr walutowy z internacjonalizacją; wyświetalnie walut,
filtr automatycznie dodaje miejsca po przecinku i oznaczenie waluty
{{ wyrażenieWalutowe | currency : symbolWaluty : miejscaPoPrzec}}
{{7 | currency}} - 7,00 zł
{{13.9501 | currency:’PLN’:1}} - 14,0 PLN
date - filtr wyświetlania daty (obiekt daty, timestamp albo string)
{{ wyrażenieDatyCzasu | date : format : strefaCzasowa}}
{{’1427110041593’ | date:’MM/dd/yyyy @ h:mma’}} - 03/23/2015 @ 12:27PM
{{sklep.data | date:"MM-dd-yy ’godz.’ h:mm:ss"}} - 03-23-15 godz. 1:09:29
filter - wybiera podzbiór z tablicy i zwraca go jako nową tablicę
{{ wyrażenieTablica | filter : predykat : precyzjeDokładność}}
<div ng-init="friends = [{name:’John’, phone:’555-1276’},
{name:’Mary’, phone:’800-BIG-MARY’},
{name:’Mike’, phone:’555-4321’},
{name:’Adam’, phone:’555-5678’},
{name:’Julie’, phone:’555-8765’},
{name:’Juliette’, phone:’555-5678’}]">
</div>
{{friends|filter:12:strict}} - [{"name":"John","phone":"555-1276"}]
Angular, cz. I
17/48
Lista filtrów II
json - konwertuje obiekty JavaScript do formatu json
{{ wyrażenieObjektJS | json : liczbaSpacji}}
<pre id="custom-spacing">{{ {’name’:’value’, age:12.4} | json:4 }}</pre>
{
"name": "value",
"age": 12.4
}
limitTo - ograniczenie wyświetlanego napisu
{{ wyrażenieWejściowe | limitTo : długośćNaWyjściu : początek}}
{{’Slonce jest dzisiaj wysoko.’ | limitTo:4}} - Slon <br>
{{’Slonce jest dzisiaj wysoko.’ | limitTo:4:7}} - jest <br>
{{’Slonce jest dzisiaj wysoko.’ | limitTo:-4}} - oko.<br>
{{’Slonce jest dzisiaj wysoko.’ | limitTo:-4:6}} - once<br>
{{’Slonce jest dzisiaj wysoko.’ | limitTo:-4:-6}} - aj w<br>
<div ng-repeat="rzecz in sklep.produkty | limitTo:3"> - tylko 3 elementy
lowercase - zmiana na małe litery
{{’Skrót JavaScript ...’ | lowercase}} - skrót javascript ...
Angular, cz. I
18/48
Lista filtrów III
number - formatuje liczby jako napisy z liczbą miejsc po przecinku
{{ wyrażenieLiczbowe | number : miejscaPoPrzecinku}}
<span>{{ 123.456789 | number }}</span> - 123,457
<span>{{ 123.456789 | number:0}}</span> - 123
<span>{{-123.456789 | number:4}}</span> - -123,4568
orderBy - wyświetlanie według określonego porządku
{{ obiektDoPosortowania | orderBy : predykat : odwóćKolejność}}
<!-<div
<!-<div
<div
rosnąco według ceny -->
ng-repeat="rzecz in sklep.produkty | orderBy:’cena’">
malejąco według nazwy -->
ng-repeat="rzecz in sklep.produkty | orderBy:’-nazwa’">
ng-repeat="rzecz in sklep.produkty | orderBy:’nazwa’:true">
uppercase - zmiana na duże litery
{{’Ala ma kota’ | uppercase}} - ALA MA KOTA
Angular, cz. I
19/48
Wywoływanie filtrów w JavaScript
$filter(’currency’)(amount, symbol, fractionSize)
$filter(’date’)(date, format, timezone)
$filter(’filter’)(array, expression, comparator)
$filter(’json’)(object, spacing)
$filter(’limitTo’)(input, limit, begin)
$filter(’lowercase’)()
$filter(’number’)(number, fractionSize)
$filter(’orderBy’)(array, expression, reverse)
$filter(’uppercase’)()
Angular, cz. I
20/48
Tworzenie własnych filtrów I
Tworzenie własnego filtru:
urzywamy słowa kluczowego filter i dwóch parametrów:
nazwa filtru,
funkcja anonimowa bez parametrów zwracająca funkcję filtrującą,
tworzymy filtr jako składową wybranego modułu,
moduł może zawierać tylko sam filtr - dołączany w miarę potrzeb.
angular.module(’mojeFiltry’, []).filter(’mojNowyFiltr’, function() {
return function(input) {
return input ? ’\u2713’ : ’\u2718’;
};
});
angular.module(’hello’, [...,’mojeFiltry’]);
<p>{{ hello.zmienna | mojNowyFiltr }}</p>
Angular, cz. I
21/48
Tworzenie własnych filtrów II
app.js
var app = angular.module(’hello’, [ ]);
app.filter(’duzeMale’, function(){
var duzeMaleFilter = function(input) {
var napis = input.split(’’);
for (var i=0; i<napis.length; i++) {
if (i%2===0) {
napis[i] = napis[i].toUpperCase();
} else {
napis[i] = napis[i].toLowerCase();
};
};
return napis.join(’’);
};
return duzeMaleFilter;
});
index.html
<h3>{{ "Nagłówek pierwszy testujący nowy filtr" | duzeMale }}</h3>
<h3>{{ "Nagłówek drugi testujący nowy filtr" | wyrazZDuzej }}</h3>
Angular, cz. I
22/48
Moduły
Moduły są przestrzenią, w którym nasza aplikacja się znajduje.
Moduł to jakiś nasz zakapsułkowany fragment funkcjonalności.
Moduły zawierają właściwości, którym przypisujemy funkcje albo
dane, np. this.product = gem;
W modułach podajemy zależności jakie są w naszej aplikacji, np.
moduł a może zależeć od modułów b i c.
app.js
var app = angular.module(’hello’, [ ]);
angular - oznacza bibliotekę AngularJS, z której korzystamy
hello - nazwa nowo tworzonego modułu
[ ] - tutaj określamy zależności, nie można pominąć tego argumentu,
nawet jeśli moduł nie jest zależny od innych
Angular, cz. I
23/48
Dyrektywy - ng-app
Dyrektywy są atrybutami znaczników HTML, które włączają jakiś
przypisane im działanie JavaScript.
Dyrektywa ng-app:
podłącza moduł aplikacji do strony,
uruchamia moduł kiedy strona jest wczytywana,
moduł jest w pliku JS dołączonym do strony (app.js).
<!DOCTYPE html>
<html ng-app="hello">
<head>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
...
</body>
</html>
Angular, cz. I
24/48
Kontroler
W kontrolerze definiujemy zachowanie aplikacji poprzez definiowanie funkcji
i zmiennych.
Kontroler pozwala nam na pracę z danymi, które chcemy wyświetlać na
stronie.
Kilka różnych kontrolerów może być zdefiniowanych w jednym pliku *.js.
Każdy kontroler powinien odpowiadać za jakąś logiczną całość - nie może
być jeden kontroler do wszystkiego.
Do połączenia kontrolera ze stroną HTML wykorzystujemy dyrektywę
ng-controller, np. ng-controller="PanelController as panel"
Sekcje inicjalizacji zmiennych i konfiguracji umieszcza się w kontrolerze.
Angular, cz. I
25/48
IIFE
IIFE - ”Immediately Invoked Function Expression”
samowywołujące się funkcje anonimowe ==
wyrażenie funkcyjne natychmiastowo wywoływane,
wzorzec projektowy języka JavaScript,
pozwala tworzyć lokalny zasięg używając zasięgu funkcji,
nie zaśmiecamy przestrzeni globalnej, zmienne znane tylko wewnątrz
funkcji.
(function() {
// raz wywoływany kod we własnej przestrzeni
})();
(function(a, b) {
// a == ’hello’
// b == ’world’
})(’hello’, ’world’);
Angular, cz. I
26/48
Dyrektywy - ng-controller
ng-controller - pozwala dołączyć kontroler do naszego szablonu
HTML (do jakiegoś znacznika, do fagmentu drzewa DOM) z jakimś
aliasem, którego będziemy używać.
ng-controller dołącza funkcje kontrolera do strony.
Podajemy nazweKontrolera, słowo kluczowe as oraz alias, którego
będziemy używać.
Zasięg kontrolera jest tylko wewnątrz takiego znacznika, do którego
został przypisany.
<div ng-controller="HelloController as hello">
<h3>{{hello.produkt.nazwa}}</h3>
<code>{{hello.produkt.cena | currency}}</code>
<p>{{hello.produkt.opis}}</p>
</div>
Angular, cz. I
27/48
Kontroler - przykład
Kontroler jest dodawany do naszej aplikacji: app.controller(...);
Cały moduł wewnątrz autoamtycznie wywoływanej funkcji anonimowej.
Tworząc kontroler podajemy jego nazwę, tutaj HelloController
i jego zawartość jako wnętrze funkcji anonimowej
Poniżej w kontrolerze utworzono zmienną produkt, której przypisano obiekt
ciastko - jego zawartość będzie wyświetlana na stronie.
(function(){
var app = angular.module(’hello’, [ ]);
app.controller(’HelloController’, function(){
this.produkt = ciastko;
});
var ciastko = {
nazwa: ’Ciasteczka’,
cena: 2.95,
opis: ’Smaczne i zdrowe’
}
})();
Angular, cz. I
28/48
Kontroler - przykład
Dyrektywa ng-controller pozwala na wykorzystanie zmiennych kontrolera na
stronie.
Korzystamy tutaj z aliasu hello, który jest przypisany nazwie kontrolera,
tutaj HelloController.
Wyrażenia pozwalają wyświetlić zawartość obiektu produkt.
<div ng-controller="HelloController as hello">
<h3>{{hello.produkt.nazwa}}</h3>
<code>{{hello.produkt.cena | currency}}</code>
<p>{{hello.produkt.opis}}</p>
</div>
Angular, cz. I
29/48
Dyrektywy - ng-show, ng-hide
ng-show - pokazuje element HTML (gałąź drzewa DOM) kiedy wartość
wyrażenia jest prawdziwa, np.: ng-show="sklep.produkt.dostepny"
Jeśli pola dostepny w ogóle brak, to dyrektywa ng-show uzna brak pola
jako false i nie pokaze danego elementu.
ng-hide - ukrywa element kiedy wartość wyrażenia jest prawdziwa.
ng-show/ng-hide - pokazuje/ukrywa jakiś fragment drzewa DOM.
Można użyć na przykład do ukrycia galerii kiedy tablica images będzie
pusta: <div ng-show="product.images.length"> ... </div>
W dyrektywach wyrażenia można łączyć warunkami logicznymi z mniejszych
wyrażeń, np.:
ng-show="
komentarz.ocena>0 ||
komentarz.tresc.length>0 ||
komentarz.autor.length>0"
Angular, cz. I
30/48
Dyrektywy - ng-repeat
ng-repeat - dyrektywa tworzy instancje przypisanego jej szablonu (zawartość
znacznika) tyle razy, ile posiada elementów w kolekcji, którą iteruje.
Składnia: ng-repeat="nazwaZmiennej in kolekcja"
nazwaZmiennej przechowującej kolejne elementy kolekcji,
słowo kluczowe in, kolekcja - tablica, po której iterujemy.
Każda instancja ma swój własny zasięg, w którym zmienna wykorzystana w
pętli ma wartość odpwiedniego elementu kolekcji.
Można wykorzystwać specjalne właściwości, np. $index która zwraca numer
elementu w kolekcji (0..length-1)
Przykłady: ng-repeat="produkt in sklep.produkty"
<p ng-repeat="aa in [3,4,5,6,7,8]">
{{aa}} - {{$index}}
</p>
<p ng-repeat="(aa, bb) in {’a’:123, ’b’:234, ’c’:456}">
{{aa}} - {{bb}} - {{$index}}
</p>
Angular, cz. I
31/48
Dyrektywy - ng-src
ng-src - zastępuje zwykły zapis w <img src="..." />
Wykorzystujemy wyrażenia np. {{produkt.obrazy[0].caly}}
Wczytywanie obrazów odbywa się zanim zadziała analiza wyrażeń w Angular.
Trzeba użyć dyrektywy ng-src. Przykład:
<img src="{{rzecz.obrazy[0].caly}}" />
<img ng-src="{{rzecz.obrazy[0].ikona}}" />
Angular, cz. I
32/48
Dyrektywy - ng-click
ng-click - ta dyrektywa przyjmuje wyrażenie, które musi zostać wykonane,
obliczone. Można tutaj zmiennej przypiswyać różne wartości.
<h1>Karty w Twitter Bootstrap</h1>
<section>
<ul class="nav nav-pills">
<li> <a href ng-click="tab = 1">Opis</a></li>
<li> <a href ng-click="tab = 2">Specyfikacja</a></li>
<li> <a href ng-click="tab = 3">Przegląd</a></li>
</ul>
<p>Kliknięto kartę nr. {{tab}}</p>
</section>
Takie wyrażenia definiują dwukierunkowe wiązania danych:
1
kliknięcie powoduje zmianę wartości zmiennej tab,
2
wartości wyrażeń są ponownie wyznaczane kiedy właściwość ze zmienną się
zmieni (np. po kliknięciu).
Tak więc wyrażenie ”śledzi” kiedy zmieni się wartość tab i wtedy, kiedy się zmieni,
to zmiana jest od razu aktualizowana na stornie.
Angular, cz. I
33/48
Dyrektywy - ng-init
ng-init - pozwala na określenie wartości wyrażenia w danym zasięgu możemy zmiennej przypisać wartość. Można wykorzystać do określenia
wartości zmiennej przy przeładowaniu strony.
Dobrze nadaje się prototypowania, eksperymentowania przy towrzeniu kodu.
Po średniku (;) można inicjować więcej niż jedną zmienną.
W poniższym przykładzie przypisujemy zmiennej tab wartość 1
oraz zmiennej rzecz obiekt odpowiadający pierwszemu produktowi.
<h1>Trzy panele z informacjami</h1>
<section ng-init="tab = 1; rzecz = sklep.produkty[0]">
<div class="panel" ng-show="tab === 1">
<h4>Opis</h4> <p>{{rzecz.opis}}</p>
</div>
<div class="panel" ng-show="tab === 2">
<h4>Specyfikacja</h4> <p>Na razie brak...</p>
</div>
<div class="panel" ng-show="tab === 3">
<h4>Przegląd</h4> <p>Na razie nie ma...</p>
</div>
</section>
Angular, cz. I
34/48
Dyrektywy - ng-class
ng-class - pozwala na dodawanie klas do danego elementu czy całej gałęzi
DOM.
Składnia: ng-class="{ klasa:wyrażenie }"
klasa jest nazwą klasy jaką chcemy dodać, do znacznika.
wyrażenie zwraca wartość logiczną, która musi być prawdziwa żeby tę klasę
dodać do danego znacznika.
<h1>Karty w Twitter Bootstrap</h1>
<section>
<ul class="nav nav-pills">
<li ng-class="{ active:tab === 1 }">
<a href ng-click="tab = 1">Opis</a>
</li>
<li ng-class="{ active:tab === 2 }">
<a href ng-click="tab = 2">Specyfikacja</a>
</li>
...
</ul>
</section>
Angular, cz. I
35/48
Dyrektywy - ng-model
ng-model wiąże wartość elementu formularza z właściwością (zmienną).
Pozwala związać zmienne z konkretnym elementem formularza
Składnia: <input ng-model="zmienna" type="text" />
Widać tutaj dwukierunkowe wiązanie danych: zmiana w polu formularza
automatycznie aktualizuje wartości zmiennych na stronie.
<form name="komentarzeFormularz">
<p>Podgląd zmian: {{komentarz.linia}}</p>
<input ng-model="komentarz.linia" type="text" />
</form>
Angular, cz. I
36/48
Dyrektywy - ng-model
ng-model można wykorzystywać do różnych elementów formularza:
select (lista rozwijana), zmienna ma wartość wybranej pozycji z listy
textarea (obszar tekstowy), zmienna ma wartość obszaru tekstowego
checkbox (pole wyboru), zmienna związana ma wartość true lub false
text (pole tekstowe), zmienna ma wartość pola tekstowego
email (pole tekstowe do adresu email), zmienna ma wartość wpisanego maila
radio buttons (pole opcji), zmienna ma wartość wybranej opcji
date
time
...
Angular, cz. I
37/48
Dyrektywy - ng-model
<form name="komentarzeFormularz">
<blockquote>
<b>Ocena: {{komentarz.ocena}}</b>
{{komentarz.tresc}}
<cite>- {{komentarz.autor}}</cite>
<p>{{komentarz.linia}}</p>
<p>{{komentarz.daneOsobowe}}</p>
<p>{{komentarz.wybor}}</p>
</blockquote>
<select ng-model="komentarz.ocena">
<option value="0">Oceń produkt</option>
<option value="1">1 gwiazdka</option>
<option value="2">2 gwiazdki</option>
...
</select>
<textarea ng-model="komentarz.tresc"></textarea>
<input ng-model="komentarz.autor" type="email" />
<input ng-model="komentarz.linia" type="text" />
<input ng-model="komentarz.daneOsobowe" type="checkbox" /> Zgadzam się ...
<input ng-model="komentarz.wybor" type="radio" value="biały" />
<input ng-model="komentarz.wybor" type="radio" value="czerwony" />
<input type="submit" value="Oceń" />
</form>
Angular, cz. I
38/48
Dyrektywy - ng-class, ng-model
Przypisuje do paragrafu wpisane do pola tekstowego klasy:
<style type="text/css">
.strike { text-decoration: line-through; }
.bold { font-weight: bold; }
.red { color: red; }
</style>
<p ng-class="style">Using String Syntax</p>
<input type="text" ng-model="style" placeholder="Type: bold strike red">
Poniższy kod wyświetla napis „Napis dowolnym kolorem” w kolorze
podanym w polu tekstowym:
<p style="color: {{style}}">Napis dowolnym kolorem</p>
<input type="text" ng-model="style" placeholder="Wpisz kolor: red,blue...">
Angular, cz. I
39/48
Kontroler - logika wewnątrz
Kontroler zawiera:
inicjalizację zmiennych - np. tab,
funkcje operujące na tych zmiennych - tutaj selectTab(num) oraz
isSelected()
app.controller(’PanelController’, function(){
this.tab = 1;
this.selectTab = function(setTab) {
this.tab = setTab;
};
this.isSelected = function(checkTab) {
return this.tab === checkTab;
};
});
Angular, cz. I
40/48
Kontroler - logika wewnątrz
Wykorzystanie logiki kontrolera w kartach, zakładkach:
<section ng-controller="PanelController as panel"">
<ul class="nav nav-pills">
<li ng-class="{ active: panel.isSelected(1) }">
<a href ng-click="panel.selectTab(1)">Opis</a>
</li>
<li ng-class="{ active: panel.isSelected(2) }">
<a href ng-click="panel.selectTab(2)">Specyfikacja</a>
</li>
...
</ul>
</section>
Logika kontrolera w pokazywaniu elementów:
<section ng-controller="PanelController as panel">
<div class="panel" ng-show="panel.isSelected(1)">
<h4>Opis</h4> <p>{{sklep.produkty[0].opis}}</p>
</div>
<div class="panel" ng-show="panel.isSelected(2)">
<h4>Specyfikacja</h4> <p>{{sklep.produkty[0].specyfikacja}}</p>
</div>
...
</section>
Angular, cz. I
41/48
Dyrektywy - ng-submit
ng-submit - pozwala wywołać funkcję kiedy formularz jest zatwierdzany.
<form name="komentarzeFormularz"
ng-controller="ReviewController as komentarzCtrl"
ng-submit="komentarzCtrl.dodajKomentarz(rzecz)">
...
<input type="submit" value="Oceń" />
</form>
Angular, cz. I
42/48
Dyrektywy - ng-options
ng-options - ten atrybut może być wykorzystany do dynamicznego
generowania listy znaczników <option> elementu <select> używając
tablicy obiektów uzyskanej z wykonania wyrażenia zawartego w ng-options.
Składnia: ng-options="label for values in array" gdzie:
label to nazwy etykiet,
values to wartości przyporządkowane wybranym etykietom,
array to tablica, względem której są budowane pola wyboru.
Przykład: ng-options="stars+’ stars’ for stars in [5,4,3,2,1]"
<select ng-model="komentarzCtrl.komentarz.ocena"
ng-options="ocena+’ pkt.’ for ocena in [5,4,3,2,1]" required>
<option value="">Oceń produkt</option>
</select>
W powyższym przykładzie wartości wybierane będą: 5,4,3,2,1
ale etykiety do nich przypisane będą: ’5 pkt.’, ’4 pkt.’, ’3 pkt.’,...
Angular, cz. I
43/48
Walidacja - właściwości wbudowane, atrybuty
$valid - wbudowana właściwość, która automatycznie waliduje każdy
formularz, wymaga przypisanej do formularza nazwy.
Znak $ oznacza odwołanie się do właściwości, w tym przypadku formularza,
valid to właściwość wbudowana w Angular.
Właściwość ta zwraca true, false zależnie, czy formularz się waliduje czy nie.
Atrybut novalidate oznacza wyłączenie domyślnej walidacji HTML
przeprowadzanej przez niektóre przeglądarki.
Atrybut required oznacza te pola formularza, które są wymagane.
<form name="komentarzeFormularz"
ng-controller="ReviewController as komentarzCtrl"
ng-submit="komentarzCtrl.dodajKomentarz(rzecz)" novalidate>
...
<textarea ng-model="komentarzCtrl.komentarz.tresc"
placeholder="Napisz którtki opis produktu..." required>
</textarea>
...
<div> komentarzeFormularz jest {{komentarzeFormularz.$valid}}</div>
</form>
Angular, cz. I
44/48
Walidacja - blokada wysłania formularza
Wykorzystując właściwość $valid formularza należy zabezpieczyć się przed
możliwością jego wysłania.
Wystarczy dodać sprawczenie poprawności formularza w dyrektywie
ng-submit: ng-submit="komentarzeFormularz.$valid && ..."
<form name="komentarzeFormularz"
ng-controller="ReviewController as komentarzCtrl"
ng-submit="komentarzeFormularz.$valid &&
komentarzCtrl.dodajKomentarz(rzecz)" novalidate>
...
<textarea ng-model="komentarzCtrl.komentarz.tresc"
placeholder="Napisz którtki opis produktu..." required>
</textarea>
...
<div> komentarzeFormularz jest {{komentarzeFormularz.$valid}}</div>
</form>
Angular, cz. I
45/48
Walidacja - klasy związane z wprowadzaniem danych
Angular podczas wprowadzania danych do formularza sam dodaje określone klasy
do pól formularza. Klasy warte wykorzystania:
ng-pristine - występuje jeśli wartość pola formularza nie uległa jeszcze
zmianie, pole nie zostało jeszcze ”dotknięte”.
ng-invalid - informuje, że wybrane pole, np. email, nie jest poprawne.
ng-dirty - jeśli zaczniemy coś wpisywać do pola to ng-pristine zmieni się na
ng-dirty - do pola są wprowadzane dane.
ng-valid - jeśli dane są prawidłowe, np. prawidłowo wprowadzony adres
email, to element będzie oznaczony klasą ng-valid.
Przykład wykorzystania, plik style.css:
.ng-invalid.ng-dirty {
border-color: red;
}
.ng-valid.ng-dirty {
border-color: green;
}
Angular, cz. I
46/48
Walidacja wbudowana w Angular
Angular ma wbudowaną walidację najpopularnieszych typów danych wejściowych:
adresów email, <input type="email" name="email">
adresów URL, <input type="url" name="homepage">
liczb, <input type="number" name="rozmiar">,
dla liczb można sprecyzować wartość minimalną i maksymalną:
min=1 max=23
pól tekstowych, <input type="text">,
dat, <input type="date">
Walidacja w Angular:
ważna ze względu na wygodę użytkownika - natychmiastowa weryfikacja
poprawności danych,
możliwość zablokowania wysłania formularza przy niepoprawnych danych,
nie zapewnia bezpieczeństwa - zawsze wymagana jest również walidacja po
stronie serwera.
Angular, cz. I
47/48
Źródła
W wykładzie wykorzystano informacje dostępne w internecie:
https://angularjs.org/
https://docs.angularjs.org/api
https://docs.angularjs.org/tutorial
https://docs.angularjs.org/guide
http://angular.codeschool.com/
Angular, cz. I
48/48

Podobne dokumenty