ngular, cz. I 1/59 Angular, cz. I Tworzenie serwisów Web 2.0 dr inż. Robert Perliński rperlinski@icis.pcz.pl Politechnika Częstochowska Instytut Informatyki Teoretycznej i Stosowanej 5 kwietnia 2017
Angular, cz. I 2/59 Plan prezentacji 1 Framework 2 Angular 1.6.3 Instalacja, dostępne moduły Hello World Moduły Wyrażenia Kontroler, dyrektywa ng-controller Filtry Dyrektywy show, hide, repeat, src click, init, class, model Formularze Dyrektywy submit, options Sprawdzanie poprawności - walidacja Internacjonalizacja i lokalizacja Kontroler - prosta logika, Bootstrap 3 Źródła
Angular, cz. I 3/59 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 4/59 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 5/59 AngularJS - wersja 1.6.3 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/ Tutorial na W3C: https://www.w3schools.com/angular/default.asp
Angular, cz. I 6/59 Najważniejsze cechy AngularJS 1.6.3 pozwala na projektowanie interaktywnych widoków - własny kod HTML, w pełni rozszerzalny, dobrze działa z innymi bibliotekami, wiązanie danych (ang. data binding), dwukierunkowe wiązanie danych, tworzenie kontrolerów określających zachowanie elementów DOM, zbudowany na bazie czystego kodu JavaScript, umożliwia głębokie linkowanie (ang. deep linking), walidacja formularzy - znacznie poprawia wrażenie z użytkowania interfejsu, wbudowana, wygodna komunikacja z serwerem, działanie asynchroniczne dzięki obietnicom, tworzenie dyrektyw (tworzenie nowych znaczników w kodzie HTML), wielokrotne wykorzystywanie raz napisanego kodu - dyrektywy, komponenty, wspiera lokalizację, korzysta z wzroca wstrzykiwania zależności (ang. dependency injection), od początku przygotowany do prowadzenia testów jednostkowych.
Angular, cz. I 7/59 Wstrzykiwanie zależności - dependency injection Obiekt tworzący aplikację (Builder) tworzy klasę A, odczytuje jej zależności i wstrzykuje klasie A instancje potrzebnych jej usług (services). Klasa a używa obiektów wstrzykniętych usług do wykonania potrzebnych zadań.
Angular, cz. I 8/59 Podstawowy moduł AngularJS Moduł ng: wewnętrzny moduł wczytywany razem z całą aplikacją, zawiera podstawową, niezbędną funkcjonalność do działania aplikacji AngularJS. Składa sie z: funkcji, dyrektyw, obiektów, typów (obiekty czy interfejsy odpowiadające za wewnętrzne działanie AngularJS), dostawców usług (ang. provider), usług (ang. service), filtrów.
Angular, cz. I 9/59 Instalacja najnowszej wersji AngularJS Pobieramy AngularJS w wersji 1.6.3: ze strony https://angularjs.org/ z Google CDN: https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js, korzystając z NPM: npm install angular@1.6.3, korzystając z Bower a: bower install angular#1.6.3, Dołączamy moduł angular-animate.js do naszego pliku HTML: <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script> albo <script src="angular.min.js"></script> Podłączamy aplikację AngularJS do naszej strony (dowolny znacznik): <!DOCTYPE html> <html ng-app="hello"> <head>... </head> <body>... </body> </html>
Angular, cz. I 10/59 Dodatkowe moduły AngularJS I Dodatkowe moduły AngularJS: nganimate - dostarcza wsparcie dla animacji bazujących na CSS jak również bazujących na JavaScript w oparciu o wstawki programowe, ngaria - wsparcie dla najczęstszych danych ARIA przekazujące stan albo informacje semantyczne o aplikacji do użytku dla technologii wspierających, np. czytniki z ekranu dla niewidzących, ngcomponentrouter - służył do trasowania, obecnie przestarzały, ngcookies - dostarcza funkcjonalność do wygodnego odczytu/zapisu ciasteczek, ngmessageformat - poszerza funkcjonalność usługi $interpolate do personalizacji wyświetlanych wiadomości ze względu na płeć czy liczność, ngmessages - poszerzone wsparcie dla wyświetlania wiadomości w szablonach, ngmock - wspiera testowanie aplikacji napisanych w AngularJS,
Angular, cz. I 11/59 Dodatkowe moduły AngularJS II Dodatkowe moduły AngularJS: ngparseext - pozwala na wykorzystywanie znaków Unicode w identyfikatorach wewnątrz wyrażeń Angulara, ngresource - służy do korzystania z RESTful za pomocą usługi $resource, pobiera dane, operuje na nich i odsyła z powrotem, ngroute - dostarcza mechanizm trasowania i towrzenia połączeń między adresem URL, a kontrolerem i widokiem, ngsanitize - dostarcza funkcjonalności do tworzenia bezpiecznego kodu HTML (oczyszczanie z niebezpiecznych znaczników, np. script, object itp.), ngtouch - wsparcie dla urządzeń z panelem dotykowym (bazuje na implementacji obsługi zdarzeń jquery Mobile touch).
Angular, cz. I 12/59 Instalacja dodatkowego modułu AngularJS Pobieramy plik modulu (X.Y.Z to wersja Angulara, tutaj 1.6.3): z Google CDN: https://ajax.googleapis.com/ajax/libs/angularjs/x.y.z/angular-animate.js, korzystając z NPM: npm install --save angular-animate@x.y.z, korzystając z Bower a: bower install angular-animate#x.y.z, Dołączamy moduł angular-animate.js do naszego pliku HTML: <script src="path/to/angular.js"></script> <script src="path/to/angular-animate.js"></script> Wczytujemy moduł w aplikacji dodając go do zależności: angular.module('app', ['nganimate']);
Angular, cz. I 13/59 Hello World - brak jakiegokolwiek modułu index.html <!doctype html> <html ng-app> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"> </head> <body> <div> <label>imię:</label> <input type="text" ng-model="twojeimie" placeholder="wpisz tutaj swoje imię"> <hr> <h1>witaj {{twojeimie}}!</h1> </div> </body> </html>
Angular, cz. I 14/59 Hello World - główny moduł aplikacji app.js var app = angular.module('hello', [ ]); index2.html <!DOCTYPE html> <html ng-app="hello"> <head> <script src="angular.min.js"></script> <script src="app.js"></script> </head> <body> <h2>{{4 + 6 * 2}}</h2> </body> </html> Co się pojawi na stronie?
Angular, cz. I 15/59 Moduły app.js 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.produkt = lampa; 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. 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 16/59 Dyrektywa - 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 src="angular.min.js"></script> <script src="app.js"></script> </head> <body>... </body> </html>
Angular, cz. I 17/59 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 src="angular.min.js"></script> a także plik z utworzonym modułem: <script 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 18/59 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 19/59 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 20/59 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 21/59 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 22/59 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 23/59 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 24/59 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 25/59 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
Angular, cz. I 26/59 Lista filtrów II filter - wybiera podzbiór z tablicy i zwraca go jako nową tablicę {{ wyrażenietablica filter : wyrażenie : komparator : dowolnyklucz }} <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:false}} - [{"name":"john","phone":"555-1276"}] wyrażenie - predykat określający, który obiekt tablicy ma przejść dalej przez filtr komparator - określa sposób porównywania zawartości tablicy i wyrażenia: function(actual, expected) - funkcja przyjmująca obiekt i wyrażenie zwracająca true kiedy obiekt z tablicy będzie spełniał warunek wyrażenia true - dokładne, skrót dla: function(actual, expected) { return angular.equals(actual, expected)} false - wyszukiwanie dopasowanego fragmentu bez rozróżnienia wielkości znaków
Angular, cz. I 27/59 Lista filtrów III json - konwertuje obiekty JavaScript do formatu json, domyślnie 2 spacje {{ wyrażenieobjektjs json : liczbaspacji}} <pre id="custom-spacing">{{ {'name':'value', age:12} json:4 }}</pre> { } "name": "value", "age": 12 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 28/59 Lista filtrów IV 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 : wyrażenie : odwóćkolejność}} <!-- rosnąco według ceny --> <div ng-repeat="rzecz in sklep.produkty orderby:'cena'"> <!-- malejąco według nazwy --> <div ng-repeat="rzecz in sklep.produkty orderby:'-nazwa'"> <div 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 29/59 Wywoływanie filtrów w JavaScript $filter('currency')(amount, symbol, fractionsize) $filter('date')(date, format, timezone) $filter('filter')(array, expression, comparator, anypropertykey) $filter('json')(object, spacing) $filter('limitto')(input, limit, begin) $filter('lowercase')() $filter('number')(number, fractionsize) $filter('orderby')(collection, expression, reverse, comparator) $filter('uppercase')()
Angular, cz. I 30/59 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 31/59 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 32/59 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 33/59 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 34/59 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}}" />
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 35/59
Angular, cz. I 36/59 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> </div> </section> <p>na razie nie ma...</p>
Angular, cz. I 37/59 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 38/59 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 39/59 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 40/59 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 41/59 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 42/59 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 43/59 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 44/59 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 45/59 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 46/59 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; }
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/59
Angular, cz. I 48/59 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,...
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 49/59
Angular, cz. I 50/59 Obsługa liczby mnogiej - ng-pluralize Język polski (kod: pl) Kategoria Przykład Zasady jeden (one) 1 n wynosi 1 kilka (few) 2-4, 22-24, 32-34... n mod 10 w granicach 2..4 AND n mod 100 poza zakresem 12..14; wiele (many) 0, 5-21, 25-31, 35-41... 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 inne (other) 1.2, 2.07, 5.94... 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 pozwala na lepsze sprecyzowanie wyświetlanego tekstu.
Angular, cz. I 51/59 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 52/59 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 53/59 Twitter bootstrap - klasy do zakładek Klasy: nav, nav-pills oraz active <h1>karty w Twitter Bootstrap</h1> <section> <ul class="nav nav-pills"> <li> <a href>opis</a> </li> <li class="active"> <a href>specyfikacja</a> </li> <li> <a href>opinie</a> </li> </ul> </section>
Angular, cz. I 54/59 Twitter bootstrap - klasa do paneli Klasy panel można użyć do prezentacji na stronie informacji związanych z jedna sekcją umieszczonych w różnych elementach, z których tylko jeden jest pokazywany. <section> <div class="panel" ng-show="..."> <p>zawartość pierwszego panelu...</p> </div> <div class="panel" ng-show="..."> <p>zawartość drugiego panelu...</p> </div> <div class="panel" ng-show="..."> <p>zawartość trzeciego panelu...</p> </div> </section>
Angular, cz. I 55/59 Kontroler - logika wewnątrz Kontroler może 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 56/59 Wykorzystanie logiki kontroler w widoku 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> <li ng-class="{ active: panel.isselected(3) }"> <a href ng-click="panel.selecttab(3)">opinie</a> </li> </ul>...
Angular, cz. I 57/59 Panele z informacjami Trzy panele pokazujące: nazwę, specyfikację i opinie o produkcie:... <div class="panel" ng-show="panel.isselected(1)"> <h3>opis produktu</h3> <p>laptop Hewlett-Packard 250 G4 (M9T03EA)...</p> </div> <div class="panel" ng-show="panel.isselected(2)"> <h3>specyfikacja produktu</h3> <ul> <li>chipset karty graficznej: Intel HD Graphics</li> <li>dysk HDD: 500GB</li> <li>pamięć RAM (zainstalowana): 4 GB</li> <li>...</li> </ul> </div> <div class="panel" ng-show="panel.isselected(3)"> <h3>opinie o produkcie</h3> <p>do produktu nie dodano jeszcze żadnych opinii. Ty możesz być pierwszy!</p> </div> </section>
Twitter bootstrap - panele z informacjami Angular, cz. I 58/59
Angular, cz. I 59/59 Ź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/