Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00501 006398 11255521 na godz. na dobę w sumie
AngularJS. Szybkie wprowadzenie - ebook/pdf
AngularJS. Szybkie wprowadzenie - ebook/pdf
Autor: , Liczba stron: 288
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-283-1622-5 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> javascript - programowanie
Porównaj ceny (książka, ebook (-20%), audiobook).

Błyskawicznie opanuj AngularJS!

AngularJS to szkielet pozwalający tworzyć zaawansowane aplikacje działające w przeglądarce internetowej. Dzięki niemu udało się przenieść do języka JavaScript najlepsze wzorce znane z tradycyjnych języków programowania, takich jak Java czy C#. To posunięcie pozwoliło też programistom na szybsze testowanie kodu, tworzenie przejrzystej architektury oraz wydajniejszą pracę.

Jeżeli chcesz skorzystać z tych wszystkich udogodnień, musisz poznać budowę oraz najlepsze praktyki tworzenia aplikacji z wykorzystaniem AngularJS. Lektura tej książki ułatwi Ci to zadanie! Sięgnij po nią i poznaj wzorzec MVC (ang. Model-View-Controller), skonfiguruj swoje środowisko pracy oraz stwórz pierwszą aplikację. W trakcie lektury kolejnych rozdziałów będziesz zdobywać fundamentalną wiedzę na temat dyrektyw, testów jednostkowych i pracy z formularzami. Następnie nauczysz się komunikować z serwerem, korzystając z usługi $http, oraz przekonasz się, do czego służy moduł ngRoute. Na sam koniec dowiesz się, jak tworzyć, testować i korzystać z własnych dyrektyw, a także zapoznasz się z najlepszymi praktykami, które ułatwią Ci codzienne życie. Dzięki tej książce błyskawicznie poznasz i wykorzystasz możliwości AngularJS!

Praktyczne wprowadzenie do świata AngularJS!



Shyam Seshadri — właściciel i prezes firmy Fundoo Solutions z siedzibą w Bombaju. Zajmuje się rozwojem produktów przeznaczonych na rynek indyjski oraz prowadzi szkolenia i konsultacje dotyczące szkieletu AngularJS i NodeJS.

Brad Green — kierownik projektów inżynieryjnych w Google. Zaangażowany w projekt AngularJS. Wcześniej zdobywał doświadczenie w branży mobilnej oraz współpracował ze Stevem Jobsem w firmie NeXT.
Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: AngularJS: Up and Running Tłumaczenie: Łukasz Piwko ISBN: 978-83-283-1619-5 © 2015 Helion S.A. Authorized Polish translation of the English edition of AngularJS: Up and Running, ISBN 9781491901946 © 2014 Shyam Seshadri Brad Green. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/angusw Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Pliki z przykładami omawianymi w książce można znaleźć pod adresem: ftp://ftp.helion.pl/przyklady/angusw.zip Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treści Wprowadzenie ............................................................................................................ 9 Wprowadzenie do AngularJS Co to jest MVC Zalety systemu AngularJS Filozofia systemu AngularJS 1. Wprowadzenie do systemu AngularJS ........................................................................ 15 15 16 17 17 23 23 23 24 25 26 Jakie zaplecze trzeba posiadać? Czy cały mój program musi być aplikacją AngularJS? Prosta aplikacja AngularJS Witaj, świecie Rozpoczynanie pracy z systemem AngularJS Podsumowanie 2. Podstawowe dyrektywy i kontrolery AngularJS .......................................................... 27 27 29 34 38 39 40 41 42 44 45 Moduły AngularJS Tworzenie pierwszego kontrolera Praca z tablicami i wyświetlanie ich zawartości Inne dyrektywy Sposób użycia dyrektywy ng-repeat Przeglądanie zawartości obiektu Zmienne pomocnicze w ng-repeat Śledzenie po identyfikatorze Zwielokrotnianie wielu elementów HTML Podsumowanie 3. Testowanie jednostkowe w systemie AngularJS ......................................................... 47 47 49 50 Testowanie jednostkowe — co i dlaczego Wprowadzenie do Karmy Wtyczki do Karmy 3 Poleć książkęKup książkę Konfiguracja Karmy Generowanie konfiguracji Karmy Szkieletowy system testów Jasmine Składnia Jasmine Przydatne dopasowywacze Jasmine Test jednostkowy dla kontrolera Uruchamianie testu jednostkowego Podsumowanie 51 53 53 53 54 55 58 59 Wyświetlanie informacji o błędach Moduł ngMessages Stylizowanie formularzy i stanów Posługiwanie się dyrektywą ng-model Praca z formularzami Wiązanie danych i modele Sprawdzanie danych z formularza i stany Obsługa błędów w formularzu 4. Formularze, pobieranie danych i usługi ...................................................................... 61 61 63 64 65 67 68 69 72 75 77 79 79 79 81 82 84 ngModelOptions Zagnieżdżanie formularzy i dyrektywa ng-form Inne kontrolki formularzy Obszary tekstowe Pola wyboru Przyciski radiowe Pola kombi i listy rozwijane Podsumowanie Usługi AngularJS Do czego służą usługi w systemie AngularJS Usługi a kontrolery Wstrzykiwanie zależności w AngularJS Wbudowane usługi systemu AngularJS Kolejność wstrzykiwania Najczęściej używane usługi systemu AngularJS 5. Wszystko o usługach AngularJS ................................................................................. 85 85 86 88 89 90 92 92 93 93 96 100 Tworzenie prostej usługi AngularJS Różnica między fabryką, usługą i dostawcą Tworzenie własnej usługi AngularJS Podsumowanie 4 (cid:95) Spis treści Poleć książkęKup książkę Pobieranie danych za pomocą usługi $http i żądań GET Obietnice Propagacja Usługa $q Wykonywanie żądań POST przy użyciu usługi $http Interfejs API usługi $http Konfiguracja 6. Komunikacja z serwerem przy użyciu usługi $http .....................................................101 101 104 105 106 107 108 109 111 111 113 115 117 120 Konfigurowanie ustawień domyślnych usługi $http Interceptory Najlepsze praktyki Moduł ngResource Podsumowanie Zaawansowane właściwości usługi $http Wstrzykiwanie zależności w testach jednostkowych Przechowywanie stanu między testami jednostkowymi 7. Testowanie jednostkowe i obiekty XHR .....................................................................121 121 123 124 126 128 129 132 134 Testowanie jednostkowe wywołań serwerowych Testy integracyjne Podsumowanie Testowanie usług Imitowanie usług Szpiedzy Czym są filtry AngularJS 8. Filtry ........................................................................................................................135 135 135 137 143 144 146 147 Stosowanie filtrów AngularJS Najczęściej używane filtry AngularJS Używanie filtrów w kontrolerach i usługach Tworzenie filtrów AngularJS Co trzeba zapamiętać o filtrach Podsumowanie 9. Testowanie jednostkowe filtrów ..............................................................................149 149 150 151 Testowanie filtru Testowanie filtru timeAgo Podsumowanie Spis treści (cid:95) 5 Poleć książkęKup książkę Trasowanie w aplikacji jednostronicowej Moduł ngRoute Opcje trasowania Wykonywanie zadań przed załadowaniem trasy za pomocą opcji resolve Usługa $routeParams Na co trzeba uważać Kompletny przykład trasowania 10. Trasowanie przy użyciu modułu ngRoute ................................................................. 153 153 155 157 159 161 162 162 171 171 174 175 176 178 Tryb HTML5 SEO a system AngularJS Statystyki przeglądania stron aplikacji AngularJS Alternatywne rozwiązania — ui-router Podsumowanie Dodatkowa konfiguracja Czym są dyrektywy Alternatywa dla dyrektyw własnych Dyrektywa ng-include Ograniczenia dyrektywy ng-include Dyrektywa ng-switch 11. Dyrektywy .............................................................................................................. 179 179 180 180 182 183 185 185 186 188 189 191 199 201 Tworzenie dyrektywy Szablon i adres szablonu Określanie sposobu użycia dyrektywy Funkcja link Zakres Atrybut replace Opcje podstawowe Podsumowanie 12. Testowanie dyrektyw .............................................................................................. 203 203 204 204 208 209 Procedura testowania dyrektywy Dyrektywa widżetu giełdowego Tworzenie testu dyrektywy Inne kwestie do rozważenia Podsumowanie Cykle życia w AngularJS 13. Zaawansowane opcje definicji dyrektyw .................................................................. 211 211 211 214 215 Cykl życia systemu AngularJS Cykl obliczeniowy Cykl życia dyrektywy 6 (cid:95) Spis treści Poleć książkęKup książkę Transkluzja Podstawy transkluzji Transkluzja — techniki zaawansowane Kontrolery dyrektyw i funkcja require Opcje klucza require Dyrektywy wejściowe i ng-model Tworzenie walidatorów Kompilacja Priorytet i terminal Integracja zewnętrzna Najlepsze praktyki Zakresy Sprzątaj i niszcz Czujki Funkcje $apply i $digest Podsumowanie 216 218 220 223 227 228 231 233 238 239 243 243 244 245 245 246 14. Testowanie kompleksowe ........................................................................................247 247 248 249 250 253 255 Do czego służy Protractor Konfiguracja wstępna Konfiguracja narzędzia Protractor Test kompleksowy Uwagi Podsumowanie Testowanie Programowanie oparte na testach Różnorodność testów Kiedy wykonywać testy 15. Porady i najlepsze praktyki .......................................................................................257 257 257 258 259 260 260 261 264 265 266 266 267 267 268 Grunt Serwowanie pojedynczego pliku JavaScript Minimalizacja Zadanie ng-templates Struktura projektu Najlepsze praktyki Struktura katalogów Biblioteki zewnętrzne Punkt początkowy Budowanie projektu Spis treści (cid:95) 7 Poleć książkęKup książkę Najlepsze praktyki Uwagi ogólne Uwagi dotyczące usług Kontrolery Dyrektywy Filtry Narzędzia i biblioteki Batarang WebStorm Moduły opcjonalne Podsumowanie 268 268 269 270 270 271 271 272 273 273 274 Skorowidz ............................................................................................................... 277 8 (cid:95) Spis treści Poleć książkęKup książkę ROZDZIAŁ 4. Formularze, pobieranie danych i usługi W poprzednich rozdziałach opisaliśmy podstawowe dyrektywy systemu AngularJS oraz objaśnili- śmy techniki tworzenia kontrolerów i przekazywania danych z kontrolerów do interfejsu użyt- kownika. Później pokazaliśmy, jak pisać testy jednostkowe przy użyciu narzędzi Karma i Jasmine. W tym rozdziale kontynuujemy pracę rozpoczętą w rozdziale 2. Pokazujemy, jak pobierać dane od użytkownika za pośrednictwem formularzy do kontrolera, aby wysłać je potem do serwera, sprawdzić lub zrobić z nimi coś innego. Następnie przejdziemy do usług AngularJS. Wyjaśnimy, jak wykorzystać niektóre z istniejących usług tego systemu oraz jak tworzyć własne usługi. Ponadto objaśnimy krótko, kiedy i dlaczego należy tworzyć usługi AngularJS. Posługiwanie się dyrektywą ng-model W poprzednim rozdziale przedstawiliśmy dyrektywę ng-bind i jej ekwiwalent w postaci notacji {{ }}. Dyrektywa ta służy do pobierania danych z kontrolerów i wyświetlania ich w interfejsie użytkow- nika. Jest to jednostronne wiązanie danych, które może być bardzo przydatne w wielu sytuacjach. Ale większość aplikacji wchodzi w interakcje z użytkownikiem i przyjmuje od niego dane. Formula- rze, od formularzy rejestracyjnych po interfejsy do zmiany danych profilowych, stanowią nieod- łączną część aplikacji sieciowych. Dlatego w systemie AngularJS utworzono dyrektywę ng-model, służącą do obsługi odbieranych danych i dwustronnego wiązania danych: !-- Plik: r04/simple-ng-model.html -- html ng-app= notesApp head meta charset= utf-8 title Notes App /title /head body ng-controller= MainCtrl as ctrl input type= text ng-model= ctrl.username / Wpisa(cid:239)e(cid:258) {{ctrl.username}} script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( notesApp , []) 61 Poleć książkęKup książkę .controller( MainCtrl , [function() { this.username = nic ; }]); /script /body /html W przykładzie tym zdefiniowaliśmy kontroler ze zmienną egzemplarzową o nazwie username. Następnie za pomocą dyrektywy ng-controller i podwójnej klamry do wiązania jednostronnego przenosimy jej wartość do kodu HTML. Nowością w tym kodzie jest element input. Jest to zwykłe pole tekstowe, ale powiązaliśmy z nim dyrektywę ng-model. Wartością tej dyrektywy jest wartość zmiennej username z kontrolera MainCtrl. W ten sposób osiągnęliśmy następujące cele: (cid:120) Gdy tworzony jest egzemplarz kodu HTML i wiązany jest z nim kontroler, następuje przeka- zanie bieżącej wartości (w tym przypadku łańcucha nic) i wyświetlenie jej w interfejsie użyt- kownika. (cid:120) Gdy użytkownik wpisze, zaktualizuje lub zmieni wartość w polu tekstowym, następuje aktu- alizacja modelu w kontrolerze. (cid:120) Gdy wartość zmiennej zmienia się w kontrolerze (bo nadeszła nowa wartość z serwera albo nastąpiła wewnętrzna zmiana stanu), wartość ta zostaje automatycznie zaktualizowana w polu wejściowym. Piękno tego rozwiązania jest podwójne: (cid:120) Jeżeli trzeba zaktualizować element formularza w interfejsie użytkownika, to wystarczy do- konać aktualizacji wartości w kontrolerze. Nie trzeba szukać pól wejściowych po identyfika- torach czy klasach. Trzeba tylko zaktualizować model. (cid:120) Jeśli trzeba pobrać najnowszą wartość wpisaną przez użytkownika w formularzu lub wpro- wadzoną w celu weryfikacji albo wysłania do serwera, to wystarczy wziąć ją z kontrolera. W kontrolerze zawsze dostępna jest najnowsza wartość. Teraz rozbudujemy nasz przykład tak, aby rzeczywiście przetwarzać informacje z formularza. Spójrz na poniższy kod źródłowy: !-- Plik: r04/simple-ng-model-2.html -- html ng-app= notesApp head meta charset= utf-8 title Notes App /title /head body ng-controller= MainCtrl as ctrl input type= text ng-model= ctrl.username input type= password ng-model= ctrl.password button ng-click= ctrl.change() Zmie(cid:241) warto(cid:258)ci /button button ng-click= ctrl.submit() Wy(cid:258)lij /button script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( notesApp , []) .controller( MainCtrl , [function() { 62 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę var self = this; self.change = function() { self.username = zmieniono ; self.password = has(cid:239)o ; }; self.submit = function() { console.log( U(cid:285)ytkownik klikn(cid:200)(cid:239) przycisk Zatwierd(cid:283) z danymi , self.username, self.password); }; }]); /script /body /html Dodaliśmy jedno pole wejściowe, które powiązaliśmy z polem o nazwie password w egzemplarzu kontrolera. Dodaliśmy też dwa przyciski: (cid:120) Pierwszy przycisk ma etykietę Zmień wartości i służy do symulowania wysyłania przez serwer danych, które mają zostać zaktualizowane w interfejsie użytkownika. Jego działanie polega na przypisywaniu najnowszych wartości do pól nazwy użytkownika i hasła w kontrolerze. (cid:120) Drugi przycisk ma etykietę Wyślij i służy do symulowania operacji wysłania formularza na serwer. Na razie przycisk ten tylko rejestruje wartość w konsoli. Najważniejszą rzeczą w obu opisanych przypadkach jest to, że kontroler ani razu nie sięgał do interfej- su użytkownika. Nie zastosowano żadnego selektora jQuery, żadnej funkcji typu findElementById ani niczego podobnego. Gdy trzeba zaktualizować interfejs użytkownika, wystarczy zmienić pola modelu w kontrolerze. Jeżeli trzeba pobrać najnowszą wartość, należy udać się po nią do kontrolera. Tak właśnie robi się to w systemie AngularJS. Teraz zobaczysz, jak wykorzystać tę wiedzę do pracy z formularzami w AngularJS. Praca z formularzami W pracy z formularzami w systemie AngularJS często stosuje się dyrektywę ng-model, służącą do przekazywania danych do i z formularza. Oprócz używania wiązania danych zalecane jest też po- sługiwanie się modelem i wiązaniami w taki sposób, aby zredukować ilość potrzebnej pracy oraz kodu źródłowego do napisania. Spójrz na poniższy przykład: !-- Plik: r04/simple-form.html -- html ng-app= notesApp head meta charset= utf-8 title Notes App /title /head body ng-controller= MainCtrl as ctrl form ng-submit= ctrl.submit() input type= text ng-model= ctrl.user.username input type= password ng-model= ctrl.user.password input type= submit value= Wy(cid:258)lij /form script Praca z formularzami (cid:95) 63 Poleć książkęKup książkę src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( notesApp , []) .controller( MainCtrl , [function() { var self = this; self.submit = function() { console.log( U(cid:285)ytkownik klikn(cid:200)(cid:239) przycisk Zatwierd(cid:283) z danymi , self.user); }; }]); /script /body /html W tym przykładzie również używamy tych samych pól wejściowych co poprzednio, ale wprowa- dziliśmy pewne zmiany: (cid:120) Pola tekstowe i przycisk wstawiliśmy do formularza. Usunęliśmy też dyrektywę ng-click z przyci- sku i zamiast niej dodaliśmy dyrektywę ng-submit do elementu formularza. Dyrektywa ng-submit ma kilka zalet w porównaniu z dyrektywą ng-click dla przycisku. Zdarzenie zatwierdzenia formularza może zostać wyzwolone na kilka sposobów, np. przez kliknięcie przycisku albo naciśnięcie klawisza Enter, gdy aktywne jest pole tekstowe. Dyrektywa ng-submit włącza się dla wszystkich tych zdarzeń, a dyrektywa ng-click — tylko dla kliknięć przycisku. (cid:120) Zamiast do ctrl.username i ctrl.password wiążemy do ctrl.user.username i ctrl.user.password. Zwróć uwagę, że w kontrolerze nie zadeklarowaliśmy obiektu użytkownika (tzn. self.user = {}). Gdy w użyciu jest dyrektywa ng-model, AngularJS automatycznie tworzy obiekty i klucze po- trzebne w procesie tworzenia wiązania danych. W tym przypadku, dopóki użytkownik nie wpisze czegoś w polu nazwy użytkownika lub hasła, nie istnieje żaden obiekt użytkownika. Pierwsza litera wpisana do któregokolwiek z tych dwóch pól powoduje utworzenie tego obiektu i przypisanie w nim wartości do odpowiedniego pola. Wiązanie danych i modele Przy projektowaniu formularzy i wybieraniu pól do związania z dyrektywą ng-model należy się zastanowić, jaki format danych będzie potrzebny. Spójrz na poniższy przykład: !-- Plik: r04/two-forms-databinding.html -- html ng-app= notesApp head meta charset= utf-8 title Notes App /title /head body ng-controller= MainCtrl as ctrl form ng-submit= ctrl.submit1() input type= text ng-model= ctrl.username input type= password ng-model= ctrl.password input type= submit value= Wy(cid:258)lij /form form ng-submit= ctrl.submit2() input type= text ng-model= ctrl.user.username 64 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę input type= password ng-model= ctrl.user.password input type= submit value= Wy(cid:258)lij /form script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( notesApp , []) .controller( MainCtrl , [function() { var self = this; self.submit1 = function() { // utworzenie obiektu użytkownika do wysłania na serwer var user = {username: self.username, password: self.password}; console.log( Pierwsze zatwierdzenie formularza z , user); }; self.submit2 = function() { console.log( Drugie zatwierdzenie formularza z , self.user); }; }]); /script /body /html W kodzie tym znajdują się dwa formularze zawierające takie same pola. Pierwszy formularz jest związany bezpośrednio ze zmiennymi username i password z kontrolera, a drugi — z kluczami username i password w obiekcie user z kontrolera. Oba formularze w momencie zatwierdzenia wyzwalają funkcję za pomocą dyrektywy ng-submit. W przypadku pierwszego formularza pola przed wysłaniem do serwera muszą zostać pobrane z kontrolera i wstawione do obiektu lub czegoś podobnego. W drugim formularzu można bezpośrednio pobrać obiekt user z kontrolera i prze- kazać go w odpowiednie miejsce. Drugie rozwiązanie jest bardziej sensowne, ponieważ wprost odwzorowuje sposób reprezentacji formularza jako obiektu w kontrolerze. Dzięki temu eliminujemy dodatkową pracę, której wyko- nanie byłoby konieczne, gdybyśmy pracowali z wartościami formularza. Sprawdzanie danych z formularza i stany Pokazaliśmy, jak tworzy się formularze i jak wykorzystać wiązanie danych w celu przekazywania danych do i z interfejsu użytkownika. Teraz chcemy przedstawić jeszcze inne zalety posługiwania się systemem AngularJS podczas pracy z formularzami, a w szczególności podczas weryfikowania poprawności danych i różnych stanów formularzy oraz ich pól: !-- Plik: r04/form-validation.html -- html ng-app= notesApp head meta charset= utf-8 title Notes App /title /head body ng-controller= MainCtrl as ctrl form ng-submit= ctrl.submit() name= myForm input type= text Sprawdzanie danych z formularza i stany (cid:95) 65 Poleć książkęKup książkę ng-model= ctrl.user.username required ng-minlength= 4 input type= password ng-model= ctrl.user.password required input type= submit value= Wy(cid:258)lij ng-disabled= myForm.$invalid /form script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( notesApp , []) .controller( MainCtrl , [function() { var self = this; self.submit = function() { console.log( U(cid:285)ytkownik klikn(cid:200)(cid:239) przycisk zatwierdzaj(cid:200)cy z , self.user); }; }]); /script /body /html Jest to zmodyfikowana wersja poprzedniego przykładu, w której dodano mechanizm weryfikacji danych. Mówiąc konkretnie, wyłączamy przycisk zatwierdzania, dopóki użytkownik nie wypełni wszystkich wymaganych pól. Oto jak to zrobiliśmy: 1. Nadaliśmy formularzowi nazwę myForm, którą będziemy mogli się później posługiwać. 2. Użyliśmy znaczników z obsługą weryfikacji danych HTML5 i do każdego pola wejściowego dodaliśmy atrybut required. 3. Dodaliśmy weryfikator danych, ng-minlength, pilnujący, aby długość wartości w polu nazwy użytkownika wynosiła nie mniej niż cztery znaki. 4. Do przycisku zatwierdzania dodaliśmy dyrektywę ng-disabled, która wyłącza ten przycisk, jeśli jej warunek jest spełniony. 5. Jeżeli chodzi o wyłączenie możliwości zatwierdzenia formularza, wykorzystaliśmy formularz eksponujący kontroler z bieżącym stanem formularza. W tym przypadku nakazujemy przyciskowi pozostać w stanie nieaktywnym, dopóki formularz o nazwie myForm jest niepoprawny ($invalid). Jeśli do pola wejściowego zostanie zastosowany weryfikator danych, to jego wartość w modelu zostanie ustawiona dopiero wtedy, gdy pole to będzie poprawnie wypeł- nione. Innymi słowy, w poprzednim przykładzie wartość pola w zmiennej ng-model (ctrl.user.username) zostanie ustawiona dopiero wtedy, gdy osiągnie minimalną długość. Do tego czasu pozostanie pusta. Kiedy używane są formularze (z określonymi nazwami), system AngularJS tworzy obiekt FormCon (cid:180)troller, zawierający bieżący stan formularza, jak również pewne metody pomocnicze. Dostęp do tego obiektu można uzyskać przez nazwę formularza, tak jak to zrobiliśmy w poprzednim przy- kładzie z formularzem myForm. W tabeli 4.1 znajduje się opis tego, co można znaleźć w ramach stanu i co jest aktualizowane poprzez wiązanie danych. 66 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę Tabela 4.1. Stany formularza w AngularJS Stan formularza $invalid $valid $pristine $dirty $error Opis System AngularJS ustawia ten stan, gdy któryś z weryfikatorów (required, ng-minlength itd.) oznaczy którekolwiek z pól w formularzu jako niepoprawne Odwrotność poprzedniego stanu, która oznacza, że wszystkie weryfikatory w formularzu aktualnie wskazują poprawność Od tego stanu zaczynają wszystkie formularze w systemie AngularJS. Umożliwia on sprawdzenie, czy użytkownik zaczął już pisać lub modyfikować zawartość któregoś pola. Możliwe zastosowanie: wyłączanie przycisku resetowania, jeśli formularz jest pusty Odwrotność stanu $pristine, która oznacza, że użytkownik już coś zmienił w formularzu (może to cofnąć, ale bit $dirty jest już ustawiony) Obiekt przechowujący referencje do elementów formularza, które nie przeszły pomyślnie weryfikacji danych. Szerzej na ten temat piszemy w następnym podrozdziale Wszystkie opisane w tabeli stany (z wyjątkiem stanu $error) są typu logicznego, więc mogą być używane do warunkowego ukrywania, pokazywania, wyłączania i włączania elementów HTML w in- terfejsie użytkownika. Gdy użytkownik coś wpisze lub zmodyfikuje w formularzu, wartości są aktu- alizowane pod warunkiem, że używana jest dyrektywa ng-model z nazwą formularza. Obsługa błędów w formularzu Znasz już techniki weryfikacji danych na poziomie formularza, ale czasami trzeba zaimplemento- wać sprawdzanie danych dla poszczególnych pól. W poprzednim przykładzie utworzyliśmy dwa wymagane pola, z których jedno musi mieć wartość nie krótszą niż cztery znaki. Co jeszcze mo- żemy zrobić? W tabeli 4.2 znajduje się wykaz niektórych wbudowanych weryfikatorów dostępnych w systemie AngularJS. Tabela 4.2. Wbudowane weryfikatory danych systemu AngularJS Weryfikator required ng-required ng-minlength ng-maxlength ng-pattern type= email type= number type= date type= url Opis Jak napisaliśmy wcześniej, weryfikator ten oznacza pole jako wymagane i sprawia, że jest niepoprawne, dopóki nie pojawi się w nim wartość W odróżnieniu od required, oznaczającego pole jako zawsze wymagane, dyrektywa ng-required umożliwia warunkowe oznaczanie pola wejściowego jako wymaganego na podstawie logicznego warunku w kontrolerze Dyrektywa ta służy do ustawiania minimalnej długości danych w polu wejściowym Dyrektywa ta służy do ustawiania maksymalnej długości danych w polu wejściowym Poprawność danych w polu wejściowym można zweryfikować przy użyciu wyrażenia regularnego zdefiniowanego w tej dyrektywie Pole tekstowe z wbudowanym mechanizmem sprawdzania poprawności adresu e-mail Pole tekstowe z wbudowanym mechanizmem sprawdzania poprawności wartości liczbowej. Dodatkowo można określić minimalną i maksymalną wartość liczby Jeśli przeglądarka obsługuje ten typ pola formularza, powoduje on wyświetlenie elementu do wyboru daty. W przeciwnym wypadku wyświetlane jest zwykłe pole tekstowe. Model ng-model powiązany z tym polem będzie obiektem date. Data powinna być zapisana w formacie rrrr-mm-dd (np. 2009-10-24). Składnik wprowadzony w AngularJS 1.3.0 Pole tekstowe z wbudowanym mechanizmem sprawdzania poprawności adresu URL Dodatkowo można tworzyć własne weryfikatory danych, o czym szerzej piszemy w rozdziale 13. Obsługa błędów w formularzu (cid:95) 67 Poleć książkęKup książkę Wyświetlanie informacji o błędach Do czego można wykorzystać te wszystkie weryfikatory? Służą one do sprawdzania poprawności danych wprowadzonych do formularza i wyłączania w razie potrzeby przycisków zatwierdzania. Ale ponadto powinniśmy poinformować użytkownika, co zrobił źle i jak to poprawić. W AngularJS dostępne są dwa narzędzia pozwalające rozwiązać ten problem: (cid:120) model umożliwiający wyświetlanie przyjaznych dla użytkownika powiadomień o błędach; (cid:120) automatycznie dodawane i usuwane klasy CSS pozwalające na zaznaczenie miejsc, w których znaleziono błędne informacje. Najpierw przeanalizujemy technikę wyświetlania informacji o błędach na podstawie występującego problemu. Spójrz na poniższy przykład: !-- Plik: r04/form-error-messages.html -- html ng-app= notesApp head meta charset= utf-8 title Notes App /title /head body ng-controller= MainCtrl as ctrl form ng-submit= ctrl.submit() name= myForm input type= text name= uname ng-model= ctrl.user.username required ng-minlength= 4 span ng-show= myForm.uname.$error.required To pole jest obowi(cid:200)zkowe /span span ng-show= myForm.uname.$error.minlength Trzeba wpisa(cid:202) przynajmniej 4 znaki /span span ng-show= myForm.uname.$invalid Pole wype(cid:239)nione niepoprawnie /span input type= password name= pwd ng-model= ctrl.user.password required span ng-show= myForm.pwd.$error.required To pole jest obowi(cid:200)zkowe /span input type= submit value= Wy(cid:258)lij ng-disabled= myForm.$invalid /form script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( notesApp , []) .controller( MainCtrl , [function () { var self = this; 68 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę self.submit = function () { console.log( U(cid:285)ytkownik zatwierdzi(cid:239) formularz z , self.user); }; }]); /script /body /html W kontrolerze nic się nie zmieniło. Zmiany zostały wprowadzone w formularzu HTML. Oto one: 1. Najpierw dodaliśmy atrybut name do obu pól wejściowych, które chcieliśmy poddać weryfikacji. Pole nazwy użytkownika nazwaliśmy uname, a pole hasła — pwd. 2. Następnie wykorzystaliśmy wiązania formularzy AngularJS, aby umożliwić sobie znalezienie błędów w poszczególnych polach. Gdy polu wejściowemu zostanie nadana nazwa, tworzony jest dla niego model ze stanem błędu. 3. W efekcie, jeśli pole nazwy użytkownika nie zostanie wypełnione, dostęp do niego można uzy- skać przez myForm.uname.$error.required. Analogicznie w przypadku weryfikatora ng-minlength należałoby użyć myForm.uname.$error.minlength. Aby sprawdzić, czy w polu hasła została wpisana jakaś wartość, należy użyć MyForm.pwd.$error.required. 4. Ponadto pobraliśmy stan pola wejściowego za pomocą myForm.uname.$invalid. Tak samo dostępne są wszystkie pozostałe stany formularza ($valid, $pristine i $dirty). W ten sposób stworzyliśmy mechanizm wyświetlania wiadomości o błędach tylko wtedy, gdy wy- stąpi określony rodzaj błędu. Każdy z weryfikatorów wymienionych w tabeli 4.2 udostępnia klucz w obiekcie $error, przy użyciu którego można go wybrać i wyświetlić wiadomość dla użytkownika dotyczącą konkretnego rodzaju błędu. Chcesz poinformować użytkownika, że wypełnienie pola jest wymagane? W takim razie gdy użytkownik rozpocznie wpisywanie tekstu, wyświetl informację o minimalnej długości oraz odpowiedni komunikat, kiedy zostanie przekroczona długość mak- symalna. Wszystkie tego typu warunkowe powiadomienia można wyświetlać za pomocą weryfi- katorów AngularJS. Moduł ngMessages W poprzednim podrozdziale pokazaliśmy, jak warunkowo wyświetlać powiadomienia o błędach w formularzu. Ale czasami potrzebne są bardziej złożone warunki. Możemy też chcieć utworzyć wspólne powiadomienia o błędach dla wszystkich stron i pól formularzy. Do tego celu w systemie AngularJS służy opcjonalny moduł o nazwie ngMessages. Nie należy on do rdzennego pliku sys- temu (angular.js), tylko znajduje się w osobnym pliku JavaScript, który trzeba oddzielnie dołączyć do strony. Moduł ngMessages dostarcza następujące funkcje: (cid:120) możliwość łatwego definiowania wiadomości dla każdego błędu zamiast używania skompli- kowanych warunków if i show; (cid:120) możliwość porządkowania wiadomości według priorytetów; (cid:120) możliwość dziedziczenia i rozszerzania wiadomości o błędach w całej aplikacji. Obsługa błędów w formularzu (cid:95) 69 Poleć książkęKup książkę Abyś mógł używać modułu ngMessages w swoim projekcie, musisz wykonać następujące czynności: 1. Dołącz plik angular-messages.js (lub jego zminimalizowaną wersję) do pliku index.html. 2. Dodaj moduł ngMessages jako zależność do głównego modułu aplikacji. 3. Zastosuj dyrektywy ng-messages i ng-message. 4. Opcjonalnie zdefiniuj szablony dla najczęściej używanych wiadomości o błędach. Poniżej przedstawiamy kompletny przykład ilustrujący sposób wykorzystania opisywanego modułu: !-- Plik: r04/ng-messages.html -- html ng-app= notesApp head meta charset= utf-8 title Notes App /title /head body ng-controller= MainCtrl as ctrl form ng-submit= ctrl.submit1() name= simpleForm input type= email name= uname ng-model= ctrl.user1.username required ng-minlength= 6 div ng-messages= simpleForm.uname.$error ng-messages-include= error-messages /div input type= password name= pwd ng-model= ctrl.user1.password required div ng-messages= simpleForm.pwd.$error ng-messages-include= error-messages /div input type= submit value= Wy(cid:258)lij ng-disabled= simpleForm.$invalid /form form ng-submit= ctrl.submit2() name= overriddenForm input type= email name= uname ng-model= ctrl.user2.username required ng-minlength= 6 div ng-messages= overriddenForm.uname.$error ng-messages-include= error-messages div ng-message= required Wpisz nazw(cid:218) u(cid:285)ytkownika /div /div input type= password name= pwd ng-model= ctrl.user2.password required div ng-messages= overriddenForm.pwd.$error div ng-message= required Wpisz has(cid:239)o /div /div input type= submit value= Wy(cid:258)lij ng-disabled= overriddenForm.$invalid 70 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę /form script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular-messages.js /script script type= text/ng-template id= error-messages div ng-message= required To pole jest obowi(cid:200)zkowe /div div ng-message= minlength Wpisano za ma(cid:239)o znaków /div div ng-message= email Podaj prawid(cid:239)owy adres e-mail /div /script script type= text/javascript angular.module( notesApp , [ ngMessages ]) .controller( MainCtrl , [function() { var self = this; self.submit1 = function() { console.log( U(cid:285)ytkownik zatwierdzi(cid:239) formularz z danymi , self.user1); }; self.submit2 = function() { console.log( U(cid:285)ytkownik zatwierdzi(cid:239) formularz z danymi , self.user2); }; }]); /script /body /html W pierwszej chwili może się wydawać, że to długi i skomplikowany kod, ale bez trudu go zrozu- miesz dzięki poniższemu opisowi fragment po fragmencie: (cid:120) Utworzyliśmy dwa formularze zawierające po dwa pola wejściowe: na nazwę użytkownika i hasło. Pole nazwy użytkownika w obu formularzach ma trzy weryfikatory: adresu e-mail (jest typu email), oznaczający, że wypełnienie tego pola jest obowiązkowe, oraz określający, że minimalna długość danych wynosi cztery znaki. Pole hasła ma tylko weryfikator, który oznacza, że jego wypełnienie jest obowiązkowe. (cid:120) Zanim przyjrzymy się dyrektywie ng-messages, przejdziemy na koniec dokumentu. Oprócz pliku angular.js dołączamy także plik angular-messages.js zawierający kod źródłowy modułu ngMessages. Ponadto dodaliśmy ten moduł jako zależność do modułu notesApp. (cid:120) Zdefiniowaliśmy element script typu text/ng-template i z identyfikatorem error-messages. Dzięki temu możemy definiować potrzebne nam fragmenty kodu HTML wewnątrz naszego głównego pliku index.html. Zawartość tego znacznika można by też było przenieść do osob- nego pliku HTML. (cid:120) Kod HTML zdefiniowany w elemencie script zawiera domyślne powiadomienia o błędach i warunki ich wyświetlania. W tym przypadku zdefiniowaliśmy wiadomości o błędach dla weryfikatorów required i minlength. (cid:120) Teraz wracamy do formularzy, a konkretnie do formularza simpleForm. Po każdym polu two- rzymy nowy element div z dyrektywą ng-messages. Do dyrektywy tej przekazujemy obiekt $error, na podstawie którego chcemy wyświetlać wiadomości o błędach. Dyrektywa ng-messages szuka kluczy w tym obiekcie i jeśli dopasuje konkretny warunek, powoduje wyświetlenie ko- munikatu w interfejsie użytkownika. Obsługa błędów w formularzu (cid:95) 71 Poleć książkęKup książkę (cid:120) Dyrektywa ng-messages umożliwia zdefiniowanie wiadomości o błędach bezpośrednio w do- kumencie (jak w przypadku pola password w formularzu overriddenForm) lub dołączenie ich z zewnętrznego szablonu za pomocą atrybutu ng-messages-include. (cid:120) Atrybut ng-messages-include szuka osadzonego w dokumencie szablonu, czyli elementu script typu text/ng-template o określonym identyfikatorze bądź zewnętrznego pliku, który zostanie załadowany asynchronicznie przez system AngularJS. (cid:120) Kolejność definicji powiadomień w szablonie (albo jako dzieci dyrektywy ng-messages) okre- śla porządek ich wyświetlania. W jednym polu formularza może jednocześnie występować kilka błędów. W naszym przypadku w polu nazwy użytkownika może zostać wpisany tekst zawierający mniej niż sześć znaków i niereprezentujący prawidłowego adresu e-mail. Jako że minlength zdefiniowaliśmy przed email, informacja o błędzie minlength zostanie wyświetlona pierwsza. A jeśli warunek dotyczący długości tekstu będzie spełniony, zostanie wyświetlona sama wiadomość dotycząca adresu e-mail. (cid:120) W razie potrzeby wiadomości o błędach znajdujące się w ogólnych szablonach można też przesłaniać. Dla pola username w formularzu overriddenForm przesłoniliśmy wiadomość do- tyczącą błędu required, zamieniając ją na bardziej konkretną. Natomiast powiadomienia dla minlength i email pozostawiliśmy bez zmian. Moduł ngMessages rozpoznaje, które komunikaty należy zmienić, a które pozostawić. Domyślnie moduł ngMessages wyświetla tylko pierwszą wiadomość o błędzie z listy warunków ng-message. Jeśli chcemy wyświetlić wszystkie informacje o błędach, które wystąpiły, należy dodat- kowo użyć atrybutu ng-messages-multiple. Dzięki niemu zostaną pokazane wiadomości o wszyst- kich błędach, których warunki zostały spełnione. Modułu ngMessages można też używać z własnymi wymaganiami i nie tylko w połączeniu z for- mularzami. Moduł ten sprawdza wartości kluczy danego obiektu i wyświetla komunikaty, jak in- strukcja switch. Podsumowując, moduł ngMessages pozwala znacznie uprościć mechanizm obsługi błędów w for- mularzach w AngularJS. Stylizowanie formularzy i stanów Wcześniej opisaliśmy różne stany formularzy (i ich pól wejściowych) — $dirty, $valid itd. Wiesz już, jak wyświetlać wybrane powiadomienia o błędach i wyłączać przyciski na podstawie tych wa- runków, ale nie umiesz jeszcze wyróżniać wybranych pól formularza lub całych formularzy za pomocą arkuszy stylów. Jedną możliwością jest użycie stanów formularzy i pól wejściowych w połączeniu z dyrektywą ng-class w celu dodania np. klasy dirty, gdy spełniony jest warunek myForm.$dirty. Jednak w systemie AngularJS istnieje prostsze rozwiązanie. Dla każdego z opisanych wcześniej stanów AngularJS dodaje i usuwa klasy CSS, opisane w tabeli 4.3, do formularzy i elementów wejściowych. Analogicznie dla każdego weryfikatora dodanego do pól wejściowych również otrzymujemy klasę CSS o podobnej nazwie, jak widać w tabeli 4.4. 72 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę Tabela 4.3. Klasy CSS dla stanów formularzy Stan $invalid $valid $pristine $dirty Klasa CSS ng-invalid ng-valid ng-pristine ng-dirty Tabela 4.4. Klasy CSS dla stanów pól wejściowych Stan pola wejściowego Klasa CSS $invalid $valid $pristine $dirty required min max minlength maxlength pattern url email date number ng-invalid ng-valid ng-pristine ng-dirty ng-valid-required lub ng-invalid-required ng-valid-min lub ng-invalid-min ng-valid-max lub ng-invalid-max ng-valid-minlength lub ng-invalid-minlength ng-valid-maxlength lub ng-invalid-maxlength ng-valid-pattern lub ng-invalid-pattern ng-valid-url lub ng-invalid-url ng-valid-email lub ng-invalid-email ng-valid-date lub ng-invalid-date ng-valid-number lub ng-invalid-number Oprócz stanu pola wejściowego AngularJS pobiera nazwę weryfikatora (number, maxlength, pattern itd.) i w zależności od tego, czy warunek tego weryfikatora został spełniony, czy nie, dodaje klasę ng-valid-nazwa_weryfikatora lub ng-invalid-nazwa_weryfikatora. Spójrzmy na przykład wykorzystania tego do wyróżniania pól wejściowych na różne sposoby: !-- Plik: r04/form-styling.html -- html ng-app= notesApp head title Notes App /title meta charset= utf-8 style .username.ng-valid { background-color: green; } .username.ng-dirty.ng-invalid-required { background-color: red; } .username.ng-dirty.ng-invalid-minlength { background-color: lightpink; } Obsługa błędów w formularzu (cid:95) 73 Poleć książkęKup książkę /style /head body ng-controller= MainCtrl as ctrl form ng-submit= ctrl.submit() name= myForm input type= text class= username name= uname ng-model= ctrl.user.username required ng-minlength= 4 input type= submit value= Wy(cid:258)lij ng-disabled= myForm.$invalid /form script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( notesApp , []) .controller( MainCtrl , [function() { var self = this; self.submit = function() { console.log( U(cid:285)ytkownik zatwierdzi(cid:239) formularz z danymi , self.user); }; }]); /script /body /html W przykładzie tym zachowaliśmy istniejącą funkcjonalność weryfikatorów, ale usunęliśmy wia- domości o błędach. Zamiast je wyświetlać, oznaczymy wymagane pola klasami CSS. Oto szcze- gółowy opis sposobu działania powyższego kodu: (cid:120) Gdy użytkownik poprawnie wypełni pole formularza, kolor pola zmienia się na zielony. Efekt ten osiągnięto poprzez ustawienie koloru tła w klasie CSS ng-valid, która jest dodawana do pola wejściowego. (cid:120) Kolor tła na czerwony zmieniamy tylko wtedy, gdy użytkownik zacznie coś wpisywać w polu tekstowym, a potem to cofnie. Innymi słowy, ustawiamy czerwone tło, które oznacza, że pole jest wymagane, dopiero wówczas, kiedy użytkownik zmodyfikuje jego zawartość. A zatem kolor tła zmienia się na czerwony, gdy zostaną zastosowane klasy CSS ng-dirty (oznacza modyfikację zawartości pola) i ng-invalid-minlength (oznacza, że użytkownik wpisał za mało znaków). W podobny sposób można by było dodać klasę CSS wyświetlającą czerwony znak *, gdy pole jest wymagane, ale nie zostało zmienione. Przy użyciu kombinacji tych klas (oraz stanów formularza i pól wejściowych) można bez problemu sformatować i wyświetlić wszystkie informacje potrzebne użytkownikowi do poprawnego wypełnienia formularza. 74 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę ngModelOptions Jak pewnie zauważyłeś, używając dyrektywy ng-model, każde naciśnięcie klawisza sprawia, że mo- del AngularJS natychmiast aktualizuje i odświeża interfejs użytkownika. Powoduje to aktualizację całego interfejsu (jest to tzw. cykl digest cycle, który szczegółowo opisano w rozdziale 13.). Ale nie zawsze o to chodzi programiście. Czasami lepiej jest aktualizować model, gdy użytkownik na chwilę przestanie pisać albo przejdzie do następnego elementu wejściowego, co pozwala zredukować liczbę cyklów aktualizacji. W AngularJS 1.3 wprowadzono możliwość dokładnego określania sposobu działania dyrektywy ng-model i aktualizowania interfejsu użytkownika. Za pomocą dyrektywy ng-model-options można definiować następujące opcje dyrektywy ng-model: updateOn Jest to łańcuch określający, których zdarzeń pola wejściowego ma nasłuchiwać dyrektywa ng-model i dla których ma dokonywać aktualizacji interfejsu. Można użyć wartości default, oznaczającej nasłuchiwanie domyślnych zdarzeń kontrolki (dla pól tekstowych jest nim naci- śnięcie klawisza, dla pól wyboru jest to kliknięcie itd.), lub wpisać konkretną nazwę zdarzenia, np. blur. W razie potrzeby można też podać listę zdarzeń rozdzielanych spacjami. debounce Może to być liczba całkowita bądź obiekt. Opcja ta określa, ile milisekund system AngularJS ma odczekać z aktualizacją zmiennej modelu po tym, jak użytkownik przerwie wpisywanie tekstu. Jeśli przekazany zostanie obiekt, to można określić wartość debounce dla każdego zda- rzenia określonego w opcji updateOn, np. { default : 500, blur : 0}. To ustawienie po- woduje aktualizację pola tekstowego, gdy użytkownik przestanie pisać przez pół sekundy lub skończy edycję tego pola. Wartość 0 oznacza natychmiastową aktualizację. allowInvalid Domyślnie opcja ta ma wartość false, sprawiającą, że AngularJS nie zapisze wartości w zmien- nej modelu ng-model, jeśli wartość ta jest niepoprawna według obowiązujących weryfikatorów. Jeżeli wartość ma być ustawiana bez względu na stan weryfikatora, należy ustawić tę opcję na true. getterSetter Wartość logiczna umożliwiająca traktowanie wyrażenia ng-model jako metody pobierającej i ustawiającej zamiast zmiennej. Poniżej znajduje się przykład użycia dyrektywy ng-model-options w praktyce: !-- Plik: r04/ng-model-options.html -- html ng-app= modelApp head meta charset= utf-8 title Ng Model Options /title /head body ng-controller= MainCtrl as ctrl div input type= text ng-model= ctrl.withoutModelOptions ng-minlength= 5 / ngModelOptions (cid:95) 75 Poleć książkęKup książkę Wpisa(cid:239)e(cid:258) {{ctrl.withoutModelOptions}} /div div input type= text ng-model= ctrl.withModelOptions ng-model-options= ctrl.modelOptions ng-minlength= 5 / Wpisa(cid:239)e(cid:258) {{ctrl.withModelOptions()}} /div script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( modelApp , []) .controller( MainCtrl , [function() { this.withoutModelOptions = ; var _localVar = ; this.modelOptions = { updateOn: default blur , debounce: { default: 1000, blur: 0 }, getterSetter: true, allowInvalid: true }; this.withModelOptions = function(txt) { if (angular.isDefined(txt)) { _localVar = txt; } else { return _localVar; } }; }]); /script /body /html W przykładzie tym zostały wykorzystane dwa pola wejściowe. Pierwsze jest związane za pomocą dyrektywy ng-model ze zmienną withoutModelOptions. Zastosowano do niego weryfikator okre- ślający minimalną długość tekstu na pięć znaków. Wartość tego pola jest pokazywana w interfejsie użytkownika natychmiast po osiągnięciu minimalnej długości. Drugi model jest związany z funkcją pobierającą i ustawiającą (withModelOptions). Normalnie funkcja ta nie działałaby z dyrektywą ng-model, ale dlatego właśnie dodatkowo zdefiniowaliśmy ng-model-options. Wartość przekazana do ng-model-options jest obiektem, który może być zde- finiowany bezpośrednio w kodzie HTML lub, jak jest w tym przypadku, może odnosić się do zmiennej z kontrolera. W dyrektywie ng-model-options zdefiniowaliśmy następujące opcje: (cid:120) powiązanie z domyślnymi typami zdarzeń i zdarzeniem blur; (cid:120) ustawienie czasu odbicia (debounce) na 1 sekundę dla wpisywania i natychmiastowej aktuali- zacji dla zdarzenia blur; 76 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę (cid:120) powiązanie z funkcją pobierającą i ustawiającą zdefiniowaną w kontrolerze, a nie w zmiennej; (cid:120) umożliwienie ustawiania niepoprawnych wartości, dzięki czemu nawet jeśli pole formularza zostanie niepoprawnie wypełnione, nadal będziemy mieć dostęp do tej nieprawidłowej war- tości w kontrolerze. Ewentualnie można też dodać dyrektywę ngModelOptions do elementu wyższego po- ziomu (np. formularza albo elementu zawierającego całą aplikację AngularJS), aby zastosować ją domyślnie do wszystkich dyrektyw ngModel w aplikacji naraz, zamiast dodawać ją do każdego elementu z osobna. Zagnieżdżanie formularzy i dyrektywa ng-form Umiesz już tworzyć formularze oraz pobierać dane do i z kontrolerów (przez wykorzystanie wią- zania danych z modelem). Wiesz już też, jak sprawdzać poprawność informacji oraz jak forma- tować i wyświetlać warunkowe powiadomienia o błędach. W tym podrozdziale przedstawiamy techniki pracy z bardziej skomplikowanymi formularzami i grupami elementów. Czasami trzeba sprawdzić poprawność wypełnienia grupy pól formularza, a nie pojedynczych elementów. Sam element form języka HTML nie zapewnia odpowiednich możliwości w tym zakresie, ponieważ formularzy nie powinno się zagnieżdżać. W systemie AngularJS dostępna jest dyrektywa ng-form, która działa podobnie jak element form , ale umożliwia zagnieżdżanie, dzięki czemu można grupować powiązane ze sobą pola formularza w sekcje: !-- Plik: r04/nested-forms.html -- html ng-app head meta charset= utf-8 title Notes App /title /head body form novalidate name= myForm div input type= text class= username name= uname ng-model= ctrl.user.username required= placeholder= Nazwa u(cid:285)ytkownika ng-minlength= 4 / input type= password class= password name= pwd ng-model= ctrl.user.password placeholder= Has(cid:239)o required= / /div ng-form name= profile input type= text Zagnieżdżanie formularzy i dyrektywa ng-form (cid:95) 77 Poleć książkęKup książkę name= firstName ng-model= ctrl.user.profile.firstName placeholder= Imi(cid:218) required input type= text name= middleName placeholder= Drugie imi(cid:218) ng-model= ctrl.user.profile.middleName input type= text name= lastName placeholder= Nazwisko ng-model= ctrl.user.profile.lastName required input type= date name= dob placeholder= Data urodzenia ng-model= ctrl.user.profile.dob /ng-form span ng-show= myForm.profile.$invalid Wype(cid:239)nij pola formularza /span input type= submit value= Wy(cid:258)lij ng-disabled= myForm.$invalid / /form script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script /body /html W przykładzie tym zagnieździliśmy formularz w formularzu głównym, ale jako że formularzy HTML nie można zagnieżdżać, wykorzystaliśmy dyrektywę ng-form. Teraz w naszym formularzu mamy stan podrzędny, możemy szybko sprawdzać poprawność wypełnienia każdej sekcji oraz mamy dostęp do tych samych stanów wiązania i formularza, których używaliśmy do tej pory. Oto krótki opis najważniejszych cech tego kodu: (cid:120) Formularz podrzędny został utworzony za pomocą dyrektywy ng-form. Można mu nadać nazwę, aby móc odwoływać się do jego stanu. (cid:120) Stan formularza podrzędnego można sprawdzić bezpośrednio (profile.$invalid) lub przez formularz nadrzędny (myForm.profile.$invalid). (cid:120) Poszczególnych elementów formularza można używać normalnie (profile.firstName.$error. (cid:180)required). (cid:120) Formularze podrzędne i zagnieżdżone mają wpływ na formularz zewnętrzny (wartością myForm.$invalid jest true ze względu na zastosowanie wymaganych znaczników). Istnieje możliwość utworzenia formularzy podrzędnych i grup z własnymi metodami określania poprawności danych, a dyrektywa ng-form umożliwia modelowanie tych grup w kodzie HTML. 78 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę Inne kontrolki formularzy Pokazaliśmy, jak posługiwać się formularzami, dyrektywą ng-model i wiązaniami, ale tylko w od- niesieniu do zwykłych pól tekstowych. W tym podrozdziale przedstawiamy także sposoby pracy z innymi elementami formularza w AngularJS. Obszary tekstowe Obszary tekstowe w systemie AngularJS obsługuje się dokładnie tak samo jak pola tekstowe. Można tworzyć dla nich dwustronne powiązania danych oraz oznaczać je jako wymagane, np.: textarea ng-model= ctrl.user.address required /textarea Techniki wiązania danych, dostępu do stanów błędów i klasy CSS są takie same jak w przypadku zwykłych pól tekstowych. Pola wyboru Pola wyboru pod pewnymi względami są nawet łatwiejsze w obsłudze, ponieważ obsługują tylko dwie wartości: prawdę i fałsz. W efekcie dwustronne wiązanie danych ng-model do takiego pola przyjmuje wartość logiczną i określa stan zaznaczenia na podstawie tej wartości. Później wszelkie zmiany w tym polu powodują przełączenie stanu modelu: input type= checkbox ng-model= ctrl.user.agree A gdybyśmy mieli coś innego niż wartości logiczne? Co, gdybyśmy chcieli przypisać łańcuch TAK lub NIE do modelu bądź sprawić, aby pole wyboru było zaznaczane dla wartości TAK? W AngularJS dostępne są dwa atrybuty dla pól wyboru, które umożliwiają określenie własnych wartości do oznaczania prawdy i fałszu. Poniżej znajduje się przykład ich użycia: input type= checkbox ng-model= ctrl.user.agree ng-true-value= TAK ng-false-value= NIE To spowoduje ustawienie wartości pola agree na TAK, jeśli użytkownik zaznaczy pole wyboru, i na NIE w przeciwnym wypadku. Zwróć uwagę na pojedyncze cudzysłowy, w które ujęto wartości TAK i NIE. Od wersji AngularJS 1.3 atrybuty ng-true-value i ng-false-value przyjmują jako argumenty wyrażenia stałe. Wcześniej można było wpisywać wartości reprezentujące prawdę i fałsz bezpośrednio, np. ng-true-value= TAK . Ale w AngularJS 1.3 dla spójności z resztą dyrektyw wprowadzono zasadę, że atrybuty ng-true-value i ng-false-value jako argumenty przyjmują tylko wyrażenia stałe. Należy podkreślić, że obecnie nie ma możliwości przekazania do atrybutów ng-true-value i ng-false-value referencji do zmiennej. Przyjmują one wyłącznie stałe łańcuchy. Nie można odnieść się do zmiennej kontrolera dla atrybutu ng-true-value lub ng-false-value. Inne kontrolki formularzy (cid:95) 79 Poleć książkęKup książkę A co zrobić, jeśli nie chcemy korzystać z dwustronnego wiązania danych, tylko użyć pola wyboru do wyświetlenia bieżącej wartości logicznej? Jest to jednostronne wiązanie, w którym stan zazna- czenia pola wyboru zmienia się wraz ze stojącą za nim wartością, ale nie w reakcji na zaznaczenie czy usunięcie zaznaczenia tego pola. W takim przypadku można skorzystać z dyrektywy ng-checked, wiążącej się z wyrażeniami AngularJS. Gdy wartość jest prawdziwa, system AngularJS ustawia elementowi wejściowemu własność ozna- czającą, że jest zaznaczony, oraz usuwa ją, gdy wartość ta jest fałszywa. Poniższej znajduje się przy- kład zastosowania opisywanych technik: !-- Plik: r04/checkbox-example.html -- html ng-app= notesApp head meta charset= utf-8 title Notes App /title /head body ng-controller= MainCtrl as ctrl div h2 Jaki jest Twój ulubiony sport? /h2 div ng-repeat= sport in ctrl.sports label ng-bind= sport.label /label div Z wi(cid:200)zaniem: input type= checkbox ng-model= sport.selected ng-true-value= TAK ng-false-value= NIE /div div Z u(cid:285)yciem ng-checked: input type= checkbox ng-checked= sport.selected === TAK /div div Aktualny stan: {{sport.selected}} /div /div /div script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( notesApp , []) .controller( MainCtrl , [function() { var self = this; self.sports = [ {label: Koszykówka , selected: TAK }, {label: Krykiet , selected: NIE }, {label: Pi(cid:239)ka no(cid:285)na , selected: NIE }, {label: P(cid:239)ywanie , selected: TAK } ]; }]); /script /body /html 80 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę W przykładzie zdefiniowaliśmy blok ng-repeat, zawierający pola wyboru z dyrektywami ng-model i ng-checked oraz element div , w którym wyświetlono bieżący stan. Pierwsze pole wyboru wy- korzystuje tradycyjne dwustronne wiązanie danych przy użyciu dyrektywy ng-model. Natomiast drugie wykorzystuje dyrektywę ng-checked. Oznacza to, że: (cid:120) Jeśli użytkownik zaznaczy pierwsze pole wyboru, wartość selected zmieni się na TAK, ponieważ dyrektywa ng-true-value definiuje właśnie taką wartość oznaczającą prawdę. To powoduje uru- chomienie dyrektywy ng-checked i zaznaczenie drugiego pola (lub usunięcie jego zaznaczenia). (cid:120) Gdy użytkownik usunie zaznaczenie pierwszego pola wyboru, wartość selected zostaje usta- wiona na NIE dzięki dyrektywie ng-false-value. (cid:120) Drugie pole wyboru w każdym elemencie pętli wyświetla stan ng-model przy użyciu dyrekty- wy ng-checked. Powoduje ono aktualizację stanu pola wyboru za każdym razem, gdy zmieni się model ng-model. Zaznaczenie i usunięcie zaznaczenia tego drugiego pola wyboru nie ma wpływu na wartość modelu. Jeśli więc potrzebujesz dwustronnego wiązania danych, użyj dyrektywy ng-model. A jeżeli potrze- bujesz jednostronnego wiązania z polami wyboru, skorzystaj z dyrektywy ng-checked. Przyciski radiowe Przyciski radiowe są podobne do pól wyboru, ale różnią się od nich pod kilkoma względami. Można utworzyć wiele przycisków radiowych (normalnie tak się robi), z których każdy w razie zaznaczenia przypisuje inną wartość do modelu. Wartość tę można określić przy użyciu zwykłego atrybutu value elementu input . Spójrz na poniższy przykład: div ng-init= user = {gender: female } input type= radio name= gender ng-model= user.gender value= male input type= radio name= gender ng-model= user.gender value= female /div W kodzie tym zdefiniowane są dwa przyciski radiowe o takiej samej nazwie, dzięki czemu zaznaczenie jednego spowoduje usunięcie zaznaczenia drugiego. Oba te przyciski są związane z tym samym modelem (user.gender). Każdy ma określoną wartość, która zostanie zapisana w user.gender (male w przypadku pierwszego przycisku i female w przypadku drugiego). Ponadto całość znajduje się w bloku ng-init, domyślnie ustawiającym wartość user.gender na female. Dzięki temu bezpo- średnio po wczytaniu tego kodu do przeglądarki domyślnie zostanie zaznaczone drugie pole. Ale co by było, gdyby wartości były dynamiczne? Wartość do przypisania mogłaby być wybierana w kontrolerze lub innym miejscu. Wówczas należałoby użyć atrybutu AngularJS ng-value, któ- rym można posługiwać się w połączeniu z przyciskami radiowymi. Atrybut ten pobiera wyrażenie AngularJS i przypisuje do modelu wartość zwrotną tego wyrażenia: Inne kontrolki formularzy (cid:95) 81 Poleć książkęKup książkę div ng-init= otherGender = inna input type= radio name= gender ng-model= user.gender value= male M(cid:218)(cid:285)czyzna input type= radio name= gender ng-model= user.gender value= female Kobieta input type= radio name= gender ng-model= user.gender ng-value= otherGender {{otherGender}} /div W kodzie tym trzecia opcja przyjmuje wartość dynamiczną. Przypisujemy ją w bloku inicjacyjnym (ng-init), ale w prawdziwej aplikacji inicjacji dokonywano by w kontrolerze, a nie bezpośrednio w kodzie HTML. Wyrażenie ng-value= otherGender nie powoduje przypisania do user.gender wartości otherGender jako łańcucha, tylko wartości zmiennej otherGender, czyli inna. Pola kombi i listy rozwijane Ostatni element formularzy HTML (którego można też używać poza formularzami) to pole select czy lista rozwijana zwana również polem kombi. Spójrzmy na prosty przykład zastosowania takiej listy w AngularJS: div ng-init= location = Indie select ng-model= location option value= USA USA /option option value= India Indie /option option value= Other (cid:191)adne z powy(cid:285)szych /option /select /div Jest to definicja prostej listy rozwijanej powiązanej danymi ze zmienną location. Na początku zainicjowaliśmy tę zmienną wartością Indie, dzięki czemu po wczytaniu strony automatycznie zostanie zaznaczona opcja Indie. Gdy użytkownik wybierze inną opcję, do modelu ng-model zo- stanie przypisana nowa wartość atrybutu value. Do pola tego mają zastosowanie standardowe weryfikatory i stany (required itd.). Obowiązują jednak pewne ograniczenia: (cid:120) Trzeba z góry znać wartości listy. (cid:120) Wartości muszą być wpisane na sztywno. (cid:120) Wartości muszą być łańcuchami. W prawdziwie dynamicznej aplikacji niektóre z tych warunków mogą nie być spełnione. Wówczas można dynamicznie generować opcje elementu select i posługiwać się obiektami zamiast łań- cuchami. W tym celu należy wykorzystać dyrektywę ng-options. Zobaczmy, jak to się robi: 82 (cid:95) Rozdział 4. Formularze, pobieranie danych i usługi Poleć książkęKup książkę !-- Plik: r04/select-example.html -- html ng-app= notesApp head meta charset= utf-8 title Notes App /title /head body ng-controller= MainCtrl as ctrl div select ng-model= ctrl.selectedCountryId ng-options= c.id as c.label for c in ctrl.countries /select Identyfikator wybranego kraju: {{ctrl.selectedCountryId}} /div div select ng-model= ctrl.selectedCountry ng-options= c.label for c in ctrl.countries /select Wybrany kraj: {{ctrl.selectedCountry}} /div script src= https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js /script script type= text/javascript angular.module( notesApp , []) .controller( MainCtrl , [function() { this.countries = [ {label: USA , id: 1}, {label: Indie , id: 2}, {label: Inny , id: 3} ]; this.selectedCountryId = 2; this.selectedCountry = this.countries[1]; }]); /script /body /html W przykładzie tym zdefiniowano dwie listy rozwijane, z których każda jest związana z innym mode- lem w kontrolerze. Pierwszy element select jest związany z modelem ctrl.selectedCountryId, a drugi — z modelem ctrl.selectedCountry. Zauważ, że pierwszy jest liczbą, a drugi obiektem. Jak to możliwe? (cid:120) W każdym elemencie select zdefiniowaliśmy atrybut ng-options, umożliwiający przegląda- nie tablicy (albo obiektu, podobnie jak przy użyciu dyrektywy ng-repeat opisanej w podroz- dziale „Praca z tablicami i wyświetlanie ich zawartości”) i wyświetlanie dynamicznych opcji. (cid:120)
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

AngularJS. Szybkie wprowadzenie
Autor:
,

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: