Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00537 008656 10441554 na godz. na dobę w sumie
AngularJS. Tworzenie aplikacji webowych. Receptury - ebook/pdf
AngularJS. Tworzenie aplikacji webowych. Receptury - ebook/pdf
Autor: Liczba stron: 328
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-283-2149-6 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> javascript - programowanie
Porównaj ceny (książka, ebook (-20%), audiobook).
AngularJS jest popularnym frameworkiem służącym do pisania aplikacji internetowych o różnej skali. Jest to świetny projekt open source, dzięki któremu praca staje się wydajna i przyjemna. Tworzenie oprogramowania mającego naprawdę wysoką jakość wymaga od programisty stałego rozwijania umiejętności. Konieczne jest doskonałe opanowanie narzędzi programistycznych i uczenie się nowych funkcji, które one oferują. Proces ten w istocie nigdy się nie kończy.

Jeśli już znasz podstawowe cechy AngularJS i postanowiłeś nabyć biegłości w pracy z tym frameworkiem, to masz w rękach książkę przeznaczoną dla Ciebie. Przedstawione w niej metodologie i strategie pozwolą Ci na sprawne budowanie wydajnych i skalowalnych aplikacji internetowych. W tym praktycznym poradniku znajdziesz ponad 90 łatwych do wykonania receptur. Od razu zaczniesz korzystać z praktycznych rozwiązań. Z pewnością docenisz jasne podejście do problemów, klarowne wyjaśnienia i czytelne wskazówki dotyczące tworzenia aplikacji produkcyjnych. Oczywiście nie zabrakło licznych fragmentów kodu opatrzonego komentarzem.

Dzięki tej książce:

AngularJS to świetne narzędzie — poznaj jego tajniki!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: AngularJS Web Application Development Cookbook Tłumaczenie: Radosław Meryk ISBN: 978-83-283-2148-9 Copyright © Packt Publishing 2014. First published in the English language under the title „AngularJS Web Application Development Cookbook – (9781783283354)”. Polish edition copyright © 2016 by Helion SA. All rights reserved. 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/anjsre Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis tre(cid:258)ci O autorze O recenzentach Przedmowa Rozdzia(cid:239) 1. Maksymalne wykorzystanie mo(cid:285)liwo(cid:258)ci AngularJS Wprowadzenie Budowanie prostych dyrektyw na poziomie elementu Omówienie spektrum dyrektyw Manipulowanie modelem DOM Dyrektywy (cid:239)(cid:200)cz(cid:200)ce Interfejs z dyrektyw(cid:200) z wykorzystaniem odizolowanego zakresu Interakcje pomi(cid:218)dzy zagnie(cid:285)d(cid:285)onymi dyrektywami Opcjonalne kontrolery zagnie(cid:285)d(cid:285)onych dyrektyw Dziedziczenie zakresu dyrektywy Szablony dyrektyw Odizolowany zakres Transkluzje dyrektyw Dyrektywy rekurencyjne Rozdzia(cid:239) 2. Rozszerzenie zestawu narz(cid:218)dzi o filtry i typy us(cid:239)ug Wprowadzenie Wykorzystywanie filtrów uppercase i lowercase U(cid:285)ywanie filtrów number i currency U(cid:285)ywanie filtra date Debugowanie z wykorzystaniem filtra json U(cid:285)ywanie filtrów danych na zewn(cid:200)trz szablonu Wykorzystanie wbudowanych filtrów wyszukiwania Tworzenie (cid:239)a(cid:241)cuchów filtrów Tworzenie niestandardowych filtrów danych Tworzenie niestandardowych filtrów wyszukiwania Filtrowanie z wykorzystaniem niestandardowych komparatorów Budowanie filtra wyszukiwania od podstaw Budowanie niestandardowego filtra wyszukiwania od podstaw U(cid:285)ywanie warto(cid:258)ci i sta(cid:239)ych us(cid:239)ug 9 10 11 17 18 18 20 25 27 30 34 36 37 39 42 43 46 53 54 54 56 59 61 63 65 67 69 72 74 76 79 81 Poleć książkęKup książkę Spis tre(cid:286)ci U(cid:285)ywanie fabryk us(cid:239)ug Korzystanie z us(cid:239)ug Korzystanie z dostawców us(cid:239)ug Korzystanie z dekoratorów us(cid:239)ug Rozdzia(cid:239) 3. Animacje w AngularJS Wprowadzenie Tworzenie prostych animacji typu fade in i fade out Replikowanie metod slideUp() i slideDown() biblioteki jQuery Tworzenie animacji wej(cid:258)ciowych z wykorzystaniem ngIf Tworzenie animacji leave i concurrent z wykorzystaniem ngView Tworzenie animacji move za pomoc(cid:200) ngRepeat Tworzenie animacji addClass za pomoc(cid:200) ngShow Tworzenie animacji removeClass za pomoc(cid:200) ngClass Tworzenie wsadowych animacji stagger Rozdzia(cid:239) 4. Kreowanie i organizowanie aplikacji Wprowadzenie R(cid:218)czne (cid:239)adowanie aplikacji Bezpieczne u(cid:285)ywanie metody $apply Organizacja pliku aplikacji i modu(cid:239)ów Ukrywanie frameworka AngularJS przed u(cid:285)ytkownikiem Zarz(cid:200)dzanie szablonami aplikacji Sk(cid:239)adnia Controller as Rozdzia(cid:239) 5. Praca z zakresami i modelem Wprowadzenie Konfigurowanie zdarze(cid:241) frameworka AngularJS i korzystanie z nich Zarz(cid:200)dzanie dziedziczeniem obiektu $scope Praca z formatkami frameworka AngularJS Korzystanie z elementów select i dyrektywy ngOptions Budowanie magistrali zdarze(cid:241) Rozdzia(cid:239) 6. Testowanie w AngularJS Wprowadzenie Konfigurowanie i uruchamianie (cid:258)rodowiska testowego w programach Yeoman i Grunt Jak dzia(cid:239)a Protractor? W(cid:239)(cid:200)czanie testów E2E i Protractor w systemie Grunt Pisanie prostych testów jednostkowych Pisanie prostych testów E2E Konfigurowanie prostej makiety serwera backend Pisanie testów DAMP U(cid:285)ywanie wzorca testów Obiekt strony Rozdzia(cid:239) 7. Szybki AngularJS Wprowadzenie Miny-pu(cid:239)apki frameworka AngularJS Tworzenie uniwersalnego wywo(cid:239)ania zwrotnego dla obserwatorów Inspekcja obserwatorów aplikacji 6 83 85 86 88 91 91 92 96 99 105 112 121 126 131 135 135 135 138 143 146 148 152 155 155 156 159 170 177 184 191 191 192 195 196 200 206 211 214 216 223 223 224 226 227 Poleć książkęKup książkę Spis tre(cid:286)ci Skuteczne stosowanie typów $watch i zarz(cid:200)dzanie nimi Optymalizowanie aplikacji z wykorzystaniem obserwatorów referencji Optymalizowanie aplikacji z wykorzystaniem obserwatorów równo(cid:258)ci Optymalizowanie aplikacji z wykorzystaniem obiektu $watchCollection Optymalizowanie aplikacji poprzez wyrejestrowywanie obserwatorów Optymalizowanie wyra(cid:285)e(cid:241) obserwatorów z wi(cid:200)zaniem szablonów Optymalizowanie aplikacji z wykorzystaniem fazy kompilacji w ng-repeat Optymalizowanie aplikacji z wykorzystaniem konstrukcji track by w ng-repeat Przycinanie obserwowanych modeli Rozdzia(cid:239) 8. Obietnice Wprowadzenie Implementacja prostej obietnicy (cid:146)a(cid:241)cuchy obietnic i handlerów obietnic Implementacja powiadomie(cid:241) dla obietnic Implementacja barier obietnic z wykorzystaniem wywo(cid:239)ania $q.all() Tworzenie wrapperów obietnic za pomoc(cid:200) wywo(cid:239)ania $q.when() Korzystanie z obietnic za po(cid:258)rednictwem obiektu $http U(cid:285)ywanie obietnic z us(cid:239)ug(cid:200) $resource Korzystanie z obietnic wraz z bibliotek(cid:200) Restangular W(cid:239)(cid:200)czanie obietnic do natywnych resolwerów (cid:258)cie(cid:285)ek Implementacja zagnie(cid:285)d(cid:285)onych resolwerów ui-router Rozdzia(cid:239) 9. Co nowego w AngularJS 1.3? Wprowadzenie Korzystanie z mechanizmów HTML5 do wprowadzania danych typu datetime (cid:146)(cid:200)czenie obserwatorów z wykorzystaniem kolekcji $watchGroup Sprawdzanie poprawno(cid:258)ci z wykorzystaniem dyrektywy ng-strict-di Zarz(cid:200)dzanie wej(cid:258)ciem modelu z wykorzystaniem dyrektywy ngModelOptions Wykorzystywanie stanów $touched i $submitted Porz(cid:200)dkowanie komunikatów o b(cid:239)(cid:218)dach formularzy z wykorzystaniem ngMessages Przycinanie listy obserwatorów z wykorzystaniem leniwego wi(cid:200)zania Tworzenie niestandardowych walidatorów formularzy i korzystanie z nich Rozdzia(cid:239) 10. Sztuczki frameworka AngularJS Wprowadzenie Manipulowanie aplikacj(cid:200) z poziomu konsoli Stosowanie zasady DRY podczas pisania kontrolerów Korzystanie z dyrektywy ng-bind zamiast ng-cloak Komentarze w plikach JSON Tworzenie niestandardowych komentarzy AngularJS Bezpieczne odwo(cid:239)ywanie si(cid:218) do g(cid:239)(cid:218)bokich w(cid:239)a(cid:258)ciwo(cid:258)ci za pomoc(cid:200) obiektu $parse Zapobieganie nadmiarowemu parsowaniu Skorowidz 229 231 234 236 238 239 241 243 245 247 247 248 254 259 262 264 266 269 270 272 274 279 279 280 281 283 284 289 291 294 298 303 303 304 307 309 310 312 315 318 323 7 Poleć książkęKup książkę Poleć książkęKup książkę 5 Praca z zakresami i modelem W tym rozdziale omówimy nast(cid:218)puj(cid:200)ce receptury: (cid:81) Konfigurowanie zdarze(cid:241) frameworka AngularJS i korzystanie z nich. (cid:81) Zarz(cid:200)dzanie dziedziczeniem obiektu $scope. (cid:81) Praca z formatkami frameworka AngularJS. (cid:81) Korzystanie z elementów select i dyrektywy ngOptions. (cid:81) Budowanie magistrali zdarze(cid:241). Wprowadzenie Framework AngularJS dostarcza konstrukcji pozwalaj(cid:200)cych na zarz(cid:200)dzanie modyfikowaniem danych w ca(cid:239)ej aplikacji, g(cid:239)ównie wykorzystuj(cid:200)c architektur(cid:218) modyfikacji modelu. Mechani- zmy wi(cid:200)zania danych frameworka AngularJS daj(cid:200) u(cid:285)ytkownikom mo(cid:285)liwo(cid:258)(cid:202) tworzenia rozbudo- wanych narz(cid:218)dzi na bazie tej architektury, jak równie(cid:285) tworzenia kana(cid:239)ów komunikacji, które pozwalaj(cid:200) skutecznie dotrze(cid:202) do wn(cid:218)trza aplikacji. Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury Konfigurowanie zdarze(cid:241) frameworka AngularJS i korzystanie z nich AngularJS oferuje pot(cid:218)(cid:285)n(cid:200) infrastruktur(cid:218) zdarze(cid:241), która daje mo(cid:285)liwo(cid:258)(cid:202) zarz(cid:200)dzania aplikacj(cid:200) w scenariuszach, w których wi(cid:200)zanie danych mo(cid:285)e by(cid:202) nieodpowiednie albo niepraktyczne. Nawet przy rygorystycznie zorganizowanej topologii aplikacji we frameworku AngularJS istnieje wiele zastosowa(cid:241) dla zdarze(cid:241). Jak to zrobi(cid:202)? Zdarzenia AngularJS s(cid:200) identyfikowane przez ci(cid:200)gi znaków i dostarczaj(cid:200) „(cid:239)adunku”, który mo- (cid:285)e przyj(cid:200)(cid:202) posta(cid:202) obiektu, funkcji albo prymitywu. Zdarzenie mo(cid:285)e by(cid:202) dostarczone za po- (cid:258)rednictwem zakresu nadrz(cid:218)dnego, który wywo(cid:239)uje $scope.$broadcast(), zakresu potomnego (albo tego samego zakresu), który wywo(cid:239)uje $scope.$emit(). Metody $scope.$on() mo(cid:285)na u(cid:285)y(cid:202) w dowolnym miejscu, gdzie mo(cid:285)na u(cid:285)y(cid:202) obiektu zakresu, tak jak pokazano poni(cid:285)ej: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope, $log) { $scope.$on( myEvent , function(event, data) { $log.log(event.name + obserwowane z (cid:239)adunkiem , data); }); }); Rozg(cid:239)aszanie zdarze(cid:241) Metoda $scope.$broadcast() wywo(cid:239)uje zdarzenie wewn(cid:200)trz siebie oraz we wszystkich zakre- sach potomnych. W wersji 1.2.7 frameworka AngularJS wprowadzono optymalizacj(cid:218) dla wy- wo(cid:239)ania $scope.$broadcast(), ale poniewa(cid:285) to dzia(cid:239)anie powoduje schodzenie w dó(cid:239) przez hierarchi(cid:218) zakresu w celu dotarcia do nas(cid:239)uchuj(cid:200)cych zakresów potomnych, to w przypadku nadu(cid:285)ywania tego mechanizmu istnieje mo(cid:285)liwo(cid:258)(cid:202) wprowadzenia problemów wydajno(cid:258)ci. Roz- g(cid:239)aszanie mo(cid:285)na zaimplementowa(cid:202) w nast(cid:218)puj(cid:200)cy sposób: (app.js) angular.module( myApp , []) .directive( myListener , function($log) { return { restrict: E , // ka(cid:298)da dyrektywa powinna mie(cid:252) swój w(cid:225)asny zakres scope: true, link: function(scope, el, attrs) { 156 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem // metoda do generowania zdarze(cid:276) scope.sendDown = function() { scope.$broadcast( mojeZdarzenie , {origin: attrs.local}); }; // metoda nas(cid:225)uchiwania zdarze(cid:276) $scope.$on( mojeZdarzenie , function(event, data) { $log.log( event.name + obserwowane w + attrs.local + , pochodz(cid:200)ce z + data.origin ); }); } }; }); (index.html) div ng-app= myApp my-listener local= zewn(cid:218)trzny button ng-click= sendDown() Prze(cid:258)lij w dó(cid:239) /button my-listener local= (cid:258)rodkowy my-listener local= pierwszy wewn(cid:218)trzny /my-listener my-listener local= drugi wewn(cid:218)trzny /my-listener /my-listener /my-listener /div W tej konfiguracji klikni(cid:218)cie przycisku Prze(cid:258)lij w dó(cid:239) spowoduje, (cid:285)e w konsoli przegl(cid:200)darki wy- (cid:258)wietl(cid:200) si(cid:218) nast(cid:218)puj(cid:200)ce komunikaty: mojeZdarzenie obserwowane w zewn(cid:218)trzny, pochodz(cid:200)ce z zewn(cid:218)trzny mojeZdarzenie obserwowane w (cid:258)rodkowy, pochodz(cid:200)ce z zewn(cid:218)trzny mojeZdarzenie obserwowane w pierwszy wewn(cid:218)trzny, pochodz(cid:200)ce z zewn(cid:218)trzny mojeZdarzenie obserwowane w drugi wewn(cid:218)trzny, pochodz(cid:200)ce z zewn(cid:218)trzny JSFiddle: http://jsfiddle.net/msfrisbie/dn0zjep9/ Emitowanie zdarzenia Jak mo(cid:285)na oczekiwa(cid:202), metoda $scope.$emit() wykonuje operacj(cid:218) odwrotn(cid:200) do $scope. (cid:180)$broadcast(). Wywo(cid:239)uje wszystkich s(cid:239)uchaczy zdarzenia, którzy istniej(cid:200) w obr(cid:218)bie tego samego zakresu albo dowolnego zakresu nadrz(cid:218)dnego wzd(cid:239)u(cid:285) (cid:239)a(cid:241)cucha prototypu w gór(cid:218), a(cid:285) do zakresu $rootScope. Mo(cid:285)na to zaimplementowa(cid:202) w nast(cid:218)puj(cid:200)cy sposób: 157 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury (app.js) angular.module( myApp , []) .directive( myListener , function($log) { return { restrict: E , // ka(cid:298)da dyrektywa powinna mie(cid:252) swój w(cid:225)asny zakres scope: true, link: function(scope, el, attrs) { // metoda do generowania zdarze(cid:276) scope.sendUp = function() { scope.$emit( mojeZdarzenie , {origin: attrs.local}); }; // metoda nas(cid:225)uchiwania zdarze(cid:276) scope.$on( mojeZdarzenie , function(event, data) { $log.log( event.name + obserwowane w + attrs.local + , pochodz(cid:200)ce z + data.origin ); }); } }; }); (index.html) div ng-app= myApp my-listener local= zewn(cid:218)trzny my-listener local= (cid:258)rodkowy my-listener local= pierwszy wewn(cid:218)trzny button ng-click= sendUp() Prze(cid:258)lij pierwszy w gór(cid:218) /button /my-listener my-listener local= drugi wewn(cid:218)trzny button ng-click= sendUp() Prze(cid:258)lij drugi w gór(cid:218) /button /my-listener /my-listener /my-listener /div W tym przyk(cid:239)adzie klikni(cid:218)cie przycisku Prze(cid:258)lij pierwszy w gór(cid:218) spowoduje wy(cid:258)wietlenie w konsoli przegl(cid:200)darki nast(cid:218)puj(cid:200)cych komunikatów: 158 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem mojeZdarzenie obserwowane w pierwszy wewn(cid:218)trzny, pochodz(cid:200)ce z pierwszy wewn(cid:218)trzny mojeZdarzenie obserwowane w (cid:258)rodkowy, pochodz(cid:200)ce z pierwszy wewn(cid:218)trzny mojeZdarzenie obserwowane w zewn(cid:218)trzny, pochodz(cid:200)ce z pierwszy wewn(cid:218)trzny Klikni(cid:218)cie przycisku Prze(cid:258)lij drugi w gór(cid:218) spowoduje wy(cid:258)wietlenie w konsoli przegl(cid:200)darki nast(cid:218)puj(cid:200)cych komunikatów: mojeZdarzenie obserwowane w drugi wewn(cid:218)trzny, pochodz(cid:200)ce z drugi wewn(cid:218)trzny mojeZdarzenie obserwowane w (cid:258)rodkowy, pochodz(cid:200)ce z drugi wewn(cid:218)trzny mojeZdarzenie obserwowane w zewn(cid:218)trzny, pochodz(cid:200)ce z drugi wewn(cid:218)trzny JSFiddle: http://jsfiddle.net/msfrisbie/a344o7vo/ Anulowanie rejestracji s(cid:239)uchacza zdarze(cid:241) Po utworzeniu procesu s(cid:239)uchacza zdarze(cid:241), na zasadzie podobnej do dzia(cid:239)ania metody $scope. (cid:180)$watch(), proces s(cid:239)uchacza b(cid:218)dzie istnia(cid:239) przez ca(cid:239)y czas (cid:285)ycia obiektu zakresu, do którego zosta(cid:239) do(cid:239)(cid:200)czony. Metoda $scope.$on() zwraca funkcj(cid:218) anulowania rejestracji, która musi by(cid:202) przechwycona w momencie deklaracji. Wywo(cid:239)anie tej funkcji anulowania rejestracji zapobiega ocenianiu funkcji wywo(cid:239)ania zwrotnego dla tego zdarzenia. Mo(cid:285)na to prze(cid:239)(cid:200)czy(cid:202) za pomoc(cid:200) wzorca setup/teardown w nast(cid:218)puj(cid:200)cy sposób: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope, $log) { $scope.setup = function() { $scope.teardown = $scope.$on( mojeZdarzenie ,function(event, data) { $log.log(event.name + obserwowane z (cid:239)adunkiem , data); }); }; }); Wywo(cid:239)anie $scope.setup() zainicjuje wi(cid:200)zanie zdarzenia, natomiast wywo(cid:239)anie $scope.teardown() spowoduje zniszczenie tego wi(cid:200)zania. Zarz(cid:200)dzanie dziedziczeniem obiektu $scope Zakresy w frameworku AngularJS podlegaj(cid:200) tym samym regu(cid:239)om dziedziczenia prototypowe- go, jak zwyk(cid:239)e obiekty JavaScript. Przy odpowiednim zarz(cid:200)dzaniu mog(cid:200) one by(cid:202) bardzo sku- tecznie u(cid:285)ywane w aplikacji. Istniej(cid:200) jednak pewne zagro(cid:285)enia, z których nale(cid:285)y zdawa(cid:202) sobie spraw(cid:218). Niebezpiecze(cid:241)stw mo(cid:285)na unikn(cid:200)(cid:202) dzi(cid:218)ki przestrzeganiu najlepszych praktyk. 159 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury Przygotuj si(cid:218) Przypu(cid:258)(cid:202)my, (cid:285)e aplikacja zawiera nast(cid:218)puj(cid:200)cy kod: (app.js) angular.module( myApp , []) .controller( Ctrl , function() {}) (index.html) div ng-app= myApp div ng-controller= Ctrl ng-init= data=123 input ng-model= data / div ng-controller= Ctrl input ng-model= data / /div div ng-controller= Ctrl input ng-model= data / /div /div /div Jak to zrobi(cid:202)? W zaprezentowanej konfiguracji egzemplarze obiektu $scope wewn(cid:200)trz zagnie(cid:285)d(cid:285)onych eg- zemplarzy Ctrl b(cid:218)d(cid:200) dziedziczy(cid:202) na poziomie prototypów po nadrz(cid:218)dnym obiekcie $scope egzemplarza Ctrl. W momencie (cid:239)adowania strony wszystkie trzy pola tekstowe b(cid:218)d(cid:200) wype(cid:239)- nione ci(cid:200)giem 123, a kiedy zmienimy warto(cid:258)(cid:202) input nadrz(cid:218)dnego kontrolera Ctrl, oba pola tekstowe zwi(cid:200)zane z potomnymi egzemplarzami $scope zaktualizuj(cid:200) si(cid:218) po kolei, poniewa(cid:285) wszystkie trzy s(cid:200) powi(cid:200)zane z tym samym obiektem. Jednak kiedy zmienimy warto(cid:258)ci dowol- nego pola tekstowego powi(cid:200)zanego z potomnym obiektem $scope, pozosta(cid:239)e pola tekstowe nie odzwierciedl(cid:200) tej zmiany, a wi(cid:200)zanie danych z tego pola tekstowego b(cid:218)dzie zak(cid:239)ócone do chwili ponownego za(cid:239)adowania aplikacji. Aby to naprawi(cid:202), nale(cid:285)y po prostu doda(cid:202) obiekt, który jest zagnie(cid:285)d(cid:285)ony w dowolnym pierwot- nym typie w zakresie. Mo(cid:285)na tego dokona(cid:202) w nast(cid:218)puj(cid:200)cy sposób: (index.html) div ng-app= myApp div ng-controller= Ctrl ng-init= data.value=123 input ng-model= data.value / div ng-controller= Ctrl input ng-model= data.value / /div 160 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem div ng-controller= Ctrl input ng-model= data.value / /div /div /div JSFiddle: http://jsfiddle.net/msfrisbie/penaakxy/ Teraz mo(cid:285)na zmodyfikowa(cid:202) dowolne spo(cid:258)ród trzech pól tekstowych, a zmiana b(cid:218)dzie odzwier- ciedlona na pozosta(cid:239)ych dwóch. Wszystkie trzy s(cid:200) nadal powi(cid:200)zane z tym samym obiektem $scope w obiekcie $scope nadrz(cid:218)dnego kontrolera Ctrl. Warto stosowa(cid:202) zasad(cid:218), aby w przypadku polegania na dziedziczeniu po obiekcie $scope w do- wolnej formie zawsze utrzymywa(cid:202) jeden poziom zagnie(cid:285)d(cid:285)enia obiektu dla wszystkich typów (zw(cid:239)aszcza typów prymitywnych). Kolokwialnie okre(cid:258)la si(cid:218) t(cid:218) w(cid:239)asno(cid:258)(cid:202) jako „zawsze u(cid:285)ywaj kropki”. Jak to dzia(cid:239)a? Kiedy warto(cid:258)(cid:202) w(cid:239)a(cid:258)ciwo(cid:258)ci $scope zostanie zaktualizowana na podstawie pola wej(cid:258)ciowego, powoduje to przypisanie warto(cid:258)ci do w(cid:239)a(cid:258)ciwo(cid:258)ci $scope, z któr(cid:200) to pole wej(cid:258)ciowe jest po- wi(cid:200)zane. Tak jak w przypadku dziedziczenia prototypowego, przypisanie do w(cid:239)a(cid:258)ciwo(cid:258)ci obiektu spowoduje pod(cid:200)(cid:285)anie za (cid:239)a(cid:241)cuchem prototypu a(cid:285) do oryginalnego egzemplarza, ale przypisanie do prymitywu spowoduje utworzenie nowego egzemplarza prymitywu w lokalnej w(cid:239)a(cid:258)ciwo(cid:258)ci $scope. W poprzednim przyk(cid:239)adzie przed dodaniem poprawki .value nowy, lokalny egzem- plarz by(cid:239) od(cid:239)(cid:200)czony od odziedziczonej warto(cid:258)ci, co skutkowa(cid:239)o podwójnymi warto(cid:258)ciami w(cid:239)a- (cid:258)ciwo(cid:258)ci $scope. Co dalej? Poni(cid:285)sze dwa przyk(cid:239)ady s(cid:200) uwa(cid:285)ane ze z(cid:239)e praktyki (z oczywistych powodów). Znacznie (cid:239)atwiej- sze jest utrzymywanie przynajmniej jednego poziomu zagnie(cid:285)d(cid:285)enia obiektów dla dowolnych danych, dla których jest potrzebne dziedziczenie w dó(cid:239) drzewa $scope aplikacji. Istnieje mo(cid:285)liwo(cid:258)(cid:202) ponownego ustanowienia tego dziedziczenia poprzez usuni(cid:218)cie prymitywnej w(cid:239)a(cid:258)ciwo(cid:258)ci z lokalnego obiektu $scope: (app.js) angular.module( myApp , []) .controller( outerCtrl , function($scope) { $scope.data = 123; }) 161 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury .controller( innerCtrl , function($scope) { $scope.reattach = function() { delete($scope.data); }; }); (index.html) div ng-app= myApp div ng-controller= outerCtrl input ng-model= data / div ng-controller= innerCtrl input ng-model= data / /div div ng-controller= innerCtrl input ng-model= data / button ng-click= reattach() Ponownie do(cid:239)(cid:200)cz /button /div /div /div JSFiddle: http://jsfiddle.net/msfrisbie/ghsa3nym/ Mo(cid:285)liwy jest równie(cid:285) bezpo(cid:258)redni dost(cid:218)p do nadrz(cid:218)dnego obiektu $scope za pomoc(cid:200) notacji $scope.$parent. W tym przypadku dziedziczenie jest ca(cid:239)kowicie ignorowane. Mo(cid:285)na to zrobi(cid:202) w nast(cid:218)puj(cid:200)cy sposób: (app.js) angular.module( myApp , []) .controller( Ctrl , function() {}); (index.html) div ng-app= myApp div ng-controller= Ctrl ng-init= data=123 input ng-model= data / div ng-controller= Ctrl input ng-model= $parent.data / /div div ng-controller= Ctrl input ng-model= $parent.data / /div /div /div 162 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem K(cid:239)opotliwe dyrektywy wbudowane W poprzednich przyk(cid:239)adach jawnie zademonstrowano zagnie(cid:285)d(cid:285)one zakresy, które dziedzicz(cid:200) na poziomie prototypów po nadrz(cid:218)dnym obiekcie $scope. W rzeczywistej aplikacji prawdopo- dobnie by(cid:239)oby to bardzo (cid:239)atwe do wykrycia i zdebugowania. Jednak framework AngularJS dostarcza szereg dyrektyw wbudowanych, które niejawnie tworz(cid:200) swoje w(cid:239)asne zakresy i je(cid:285)eli prototypowe dziedziczenie zakresów nie jest stosowane rozwa(cid:285)nie, mo(cid:285)e to spowodowa(cid:202) pro- blemy. Istnieje sze(cid:258)(cid:202) wbudowanych dyrektyw, które tworz(cid:200) swoje w(cid:239)asne zakresy: ngController, ngInclude, ngView, ngRepeat, ngIf oraz ngSwitch. W poni(cid:285)szych przyk(cid:239)adach pokazano wykorzystanie identyfikatora $scope $id w szablonie w celu zademonstrowania tworzenia nowego zakresu. ngController U(cid:285)ycie dyrektywy ngController powinno by(cid:202) oczywiste, poniewa(cid:285) logika kontrolera polega na do(cid:239)(cid:200)czaniu funkcji i danych do nowego zakresu potomnego utworzonego za pomoc(cid:200) dy- rektywy ngController. ngInclude Niezale(cid:285)nie od w(cid:239)(cid:200)czanej zawarto(cid:258)ci HTML, dyrektywa ng-include opakuje j(cid:200) wewn(cid:200)trz no- wego zakresu. Poniewa(cid:285) dyrektywa ng-include jest standardowo u(cid:285)ywana w celu wstawiania komponentów monolitycznej aplikacji, które nie zale(cid:285)(cid:200) od ich otoczenia, jest mniejsze praw- dopodobie(cid:241)stwo, (cid:285)e stosowanie tej dyrektywy spowoduje problemy zwi(cid:200)zane z dziedziczeniem obiektu $scope. Poni(cid:285)ej zamieszczono nieprawid(cid:239)owe rozwi(cid:200)zanie: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.data = 123; }); (index.html) div ng-app= myApp div ng-controller= Ctrl Scope id: {{ $id }} input ng-model= data / ng-include src= innerTemplate.html /ng-include /div script type= text/ng-template id= innerTemplate.html div 163 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury Scope id: {{ $id }} input ng-model= data / /div /script /div Nowy zakres wewn(cid:200)trz skompilowanej dyrektywy ng-include dziedziczy po obiekcie $scope kontrolera, ale wi(cid:200)zanie do jego prymitywnej warto(cid:258)ci powoduje taki sam problem. Oto prawid(cid:239)owe rozwi(cid:200)zanie: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.data = { val: 123 }; }); (index.html) div ng-app= myApp div ng-controller= Ctrl Scope id: {{ $id }} input ng-model= data.val / ng-include src= innerTemplate.html /ng-include /div script type= text/ng-template id= innerTemplate.html div Scope id: {{ $id }} input ng-model= data.val / /div /script /div JSFiddle: http://jsfiddle.net/msfrisbie/c8nLk676/ ngView Z perspektywy dziedziczenia prototypowanego dyrektywa ng-view dzia(cid:239)a identycznie, jak dy- rektywa ng-include. Do wstawionego skompilowanego szablonu dostarczany jest nowy potomny obiekt $scope, a prawid(cid:239)owe dziedziczenie po nadrz(cid:218)dnym zakresie $scope mo(cid:285)na osi(cid:200)gn(cid:200)(cid:202) dok(cid:239)adnie w taki sam sposób. 164 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem ngRepeat Dyrektywa ngRepeat sprawia najwi(cid:218)cej problemów, je(cid:258)li chodzi o nieprawid(cid:239)owe zarz(cid:200)dzanie dziedziczeniem obiektu $scope. Ka(cid:285)dy element stworzony przez repeater uzyskuje w(cid:239)asny zakres, a modyfikacje zakresów potomnych (takie jak edytowanie inline danych na li(cid:258)cie) nie maj(cid:200) wp(cid:239)ywu na oryginalny obiekt, je(cid:285)eli jest on powi(cid:200)zany z typami prymitywnymi. Poni(cid:285)ej zamieszczono nieprawid(cid:239)owe rozwi(cid:200)zanie: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.names = [ Alshon Jeffrey , Brandon Marshall , Matt Forte , Martellus Bennett , Jay Cutler ]; }); (index.html) div ng-app= myApp div ng-controller= Ctrl Scope id: {{ $id }} pre {{ names | json }} /pre div ng-repeat= name in names Scope id: {{ $id }} input ng-model= name / /div /div /div Zgodnie z tym, co napisano wcze(cid:258)niej, zmiana warto(cid:258)ci w polach wej(cid:258)ciowych s(cid:239)u(cid:285)y tylko zmodyfikowaniu egzemplarzy prymitywu w zakresie potomnym, a nie w oryginalnym obiekcie. Jednym ze sposobów, aby to naprawi(cid:202), jest restrukturyzacja obiektu danych w taki sposób, aby zamiast iterowania po typach pierwotnych iterowa(cid:239) po obiektach opakowuj(cid:200)cych te typy pierwotne. Oto prawid(cid:239)owe rozwi(cid:200)zanie: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.players = [ {name: Alshon Jeffrey }, 165 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury { name: Brandon Marshall }, { name: Matt Forte }, { name: Martellus Bennett }, { name: Jay Cutler } ]; }); (index.html) div ng-app= myApp div ng-controller= Ctrl Scope id: {{ $id }} pre {{ players | json }} /pre div ng-repeat= player in players Scope id: {{ $id }} input ng-model= player.name / /div /div /div JSFiddle: http://jsfiddle.net/msfrisbie/zesj1gb6/ W tym rozwi(cid:200)zaniu oryginalna tablica jest modyfikowana w(cid:239)a(cid:258)ciwie i wszystko jest w najlep- szym porz(cid:200)dku. Czasami jednak restrukturyzowanie obiektu w aplikacji nie jest wykonalne. W takim przypadku modyfikowanie tablicy (cid:239)a(cid:241)cuchów znaków na tablic(cid:218) obiektów wydaje si(cid:218) dziwnym obej(cid:258)ciem. W idealnym przypadku by(cid:239)oby lepiej, gdyby by(cid:239)o mo(cid:285)na iterowa(cid:202) po tablicy (cid:239)a(cid:241)cuchów znaków bez jej uprzedniego modyfikowania. Jest to mo(cid:285)liwe dzi(cid:218)ki skorzystaniu z konstrukcji track by w wyra(cid:285)eniu dyrektywy ng-repeat. Oto prawid(cid:239)owe rozwi(cid:200)zanie: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.players = [ Alshon Jeffrey , Brandon Marshall , Matt Forte , Martellus Bennett , Jay Cutler ]; }); (index.html) div ng-app= myApp 166 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem div ng-controller= Ctrl Scope id: {{ $id }} pre {{ players | json }} /pre div ng-repeat= player in players track by $index Scope id: {{ $id }} input ng-model= players[$index] / /div /div /div JSFiddle: http://jsfiddle.net/msfrisbie/ovas398h/ Teraz pomimo tego, (cid:285)e repeater iteruje po elementach tablicy players, to ze wzgl(cid:218)du na to, (cid:285)e potomne obiekty $scope stworzone dla ka(cid:285)dego elementu w dalszym ci(cid:200)gu b(cid:218)d(cid:200) dziedziczy(cid:202) prototyp tablicy players, repeater powi(cid:200)(cid:285)e w(cid:239)a(cid:258)ciwy element w tablicy za pomoc(cid:200) obiektu $index. Poniewa(cid:285) typy pierwotne w JavaScript s(cid:200) niemutowalne, modyfikacja elementu typu pierwot- nego w tablicy spowoduje jego ca(cid:239)kowite zast(cid:200)pienie. Gdy nast(cid:218)puje ta zamiana, to ze wzgl(cid:218)du na to, (cid:285)e przy zwyk(cid:239)ym wykorzystaniu dyrektywy ng-repeat elementy tablicy s(cid:200) identyfikowane wed(cid:239)ug ich warto(cid:258)ci tekstowej, z perspektywy dyrektywy ng-repeat sytuacja wygl(cid:200)da tak, jakby dodano nowy element. W zwi(cid:200)zku z tym ca(cid:239)a zawarto(cid:258)(cid:202) tablicy zostanie wyrenderowana od nowa — ze wzgl(cid:218)dów zwi(cid:200)zanych z wygod(cid:200) u(cid:285)ytkowania i wydajno(cid:258)ci(cid:200) ta funkcjonalno(cid:258)(cid:202) jest oczywi(cid:258)cie niepo(cid:285)(cid:200)dana. Problem rozwi(cid:200)zuje zastosowanie klauzuli track by $index w wyra- (cid:285)eniu dyrektywy ng-repeat. W tym przypadku elementy tablicy s(cid:200) identyfikowane wed(cid:239)ug indeksu, a nie warto(cid:258)ci tekstowej. To zapobiega ci(cid:200)g(cid:239)emu ponownemu renderowaniu. ngIf Poniewa(cid:285) dyrektywa ng-if niszczy zawarto(cid:258)(cid:202) modelu DOM zagnie(cid:285)d(cid:285)on(cid:200) wewn(cid:200)trz niej za ka(cid:285)dym razem, gdy wyra(cid:285)enie dyrektywy przyjmie warto(cid:258)(cid:202) false, to przy ka(cid:285)dej kompilacji wewn(cid:218)trznej zawarto(cid:258)ci odziedziczy ona nadrz(cid:218)dny obiekt $scope. Je(cid:285)eli cokolwiek wewn(cid:200)trz dyrektywy ng-if nieprawid(cid:239)owo odziedziczy po nadrz(cid:218)dnym obiekcie $scope, wtedy przy ka(cid:285)dej ponownej kompilacji dane $scope potomka b(cid:218)d(cid:200) usuni(cid:218)te. Poni(cid:285)ej zamieszczono nieprawid(cid:239)owe rozwi(cid:200)zanie: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.data 123; $scope.show = false; }); 167 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury (index.html) div ng-app= myApp div ng-controller= Ctrl Scope id: {{ $id }} input ng-model= data / input type= checkbox ng-model= show / div ng-if= show Scope id: {{ $id }} input ng-model= data / /div /div /div Za ka(cid:285)dym razem, gdy u(cid:285)ytkownik zaznaczy pole wyboru, nowo utworzony obiekt $scope odziedziczy warto(cid:258)ci po nadrz(cid:218)dnym obiekcie $scope i wyczy(cid:258)ci istniej(cid:200)ce dane. To jest oczywi- (cid:258)cie niepo(cid:285)(cid:200)dane w wielu scenariuszach. Zamiast tego problem rozwi(cid:200)zuje proste wykorzy- stanie jednego po(cid:258)redniego poziomu obiektu. Oto prawid(cid:239)owe rozwi(cid:200)zanie: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.data = { val: 123 }; $scope.show = false; }); (index.html) div ng-app= myApp div ng-controller= Ctrl Scope id: {{ $id }} input ng-model= data.val / input type= checkbox ng-model= show / div ng-if= show Scope id: {{ $id }} input ng-model= data.val / /div /div /div JSFiddle: http://jsfiddle.net/msfrisbie/hq7r5frm/ 168 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem ngSwitch Dzia(cid:239)anie dyrektywy ngSwitch pod wieloma wzgl(cid:218)dami mo(cid:285)na porówna(cid:202) do po(cid:239)(cid:200)czonego dzia(cid:239)a- nia kilku dyrektyw ngIf. Je(cid:285)eli cokolwiek wewn(cid:200)trz aktywnego obiektu $scope dyrektywy ng-if niepoprawnie odziedziczy od obiektu $scope rodzica, to przy ka(cid:285)dej ponownej kompilacji oraz aktualizacji obserwowanej warto(cid:258)ci prze(cid:239)(cid:200)cznika dane potomnego obiektu $scope b(cid:218)d(cid:200) wyczyszczone. Poni(cid:285)ej zamieszczono nieprawid(cid:239)owe rozwi(cid:200)zanie: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.data = 123; }); (index.html) div ng-app= myApp div ng-controller= Ctrl Scope id: {{ $id }} input ng-model= data / div ng-switch on= data div ng-switch-when= 123 Scope id: {{ $id }} input ng-model= data / /div div ng-switch-default Scope id: {{ $id }} Default /div /div /div /div W tym przyk(cid:239)adzie, kiedy zewn(cid:218)trzny znacznik input zostanie ustawiony na pasuj(cid:200)c(cid:200) war- to(cid:258)(cid:202) 123, wtedy wewn(cid:218)trzny znacznik input zagnie(cid:285)d(cid:285)ony w dyrektywie ng-switch zgodnie z oczekiwaniami odziedziczy t(cid:218) warto(cid:258)(cid:202). Jednak(cid:285)e w przypadku aktualizacji wewn(cid:218)trznego pola wej(cid:258)ciowego odziedziczona warto(cid:258)(cid:202) nie zostanie zmodyfikowana, poniewa(cid:285) (cid:239)a(cid:241)cuch dzie- dziczenia prototypowego jest naruszony. Oto prawid(cid:239)owe rozwi(cid:200)zanie: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.data = { 169 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury val: 123 }; }); (index.html) div ng-app= myApp div ng-controller= Ctrl Scope id: {{ $id }} input ng-model= data.val / div ng-switch on= data.val div ng-switch-when= 123 Scope id: {{ $id }} input ng-model= data.val / /div div ng-switch-default Scope id: {{ $id }} Default /div /div /div /div JSFiddle: http://jsfiddle.net/msfrisbie/8kh41wdm/ Praca z formatkami frameworka AngularJS AngularJS zapewnia (cid:258)cis(cid:239)(cid:200) integracj(cid:218) z elementami formularzy HTML. Zawiera dyrektywy pozwalaj(cid:200)ce na szybkie i (cid:239)atwe budowanie animowanych i wyposa(cid:285)onych w style strony formu- larzy wraz z mechanizmami walidacji. Jak to zrobi(cid:202)? Formularze frameworka AngularJS definiuje si(cid:218) za pomoc(cid:200) znacznika form , który odpowiada natywnej dyrektywie frameworka AngularJS. Przyk(cid:239)ad jej u(cid:285)ycia zaprezentowano w poni(cid:285)szym kodzie. Atrybut novalidate jest instrukcj(cid:200) dla przegl(cid:200)darki do zignorowania wbudowanych mechanizmów walidacji formularzy: form novalidate !-- kontrolki wej(cid:286)ciowe formularza -- /form 170 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem Kontrolki wej(cid:258)ciowe HTML nale(cid:285)y umie(cid:258)ci(cid:202) wewn(cid:200)trz znaczników form . Ka(cid:285)dy egzem- plarz znacznika form tworzy obiekt FormController, który zarz(cid:200)dza wszystkimi kontrolkami i zagnie(cid:285)d(cid:285)onymi formularzami. Na bazie tego mechanizmu jest zbudowana ca(cid:239)a infrastruktu- ra obs(cid:239)ugi formularzy frameworka AngularJS. Poniewa(cid:285) przegl(cid:200)darki nie pozwalaj(cid:200) zagnie(cid:285)d(cid:285)a(cid:202) znaczników form, do zagnie(cid:285)d(cid:285)ania formularzy nale(cid:285)y stosowa(cid:202) dyrektyw(cid:218) ng-form. Co oferuj(cid:200) formularze? Przypu(cid:258)(cid:202)my, (cid:285)e w aplikacji mamy kontroler zawieraj(cid:200)cy formularz w nast(cid:218)puj(cid:200)cej postaci: div ng-controller= Ctrl form novalidate name= myform input name= myinput ng-model= formdata.myinput / /form /div W przypadku aplikacji zawieraj(cid:200)cej kontroler w tej postaci do obiektu $scope kontrolera jest dostarczany konstruktor obiektu FormController za pomoc(cid:200) $scope.myform. Konstruktor ten zawiera wiele przydatnych atrybutów i funkcji. Dost(cid:218)p do pojedynczych pozycji formularza dla ka(cid:285)dego pola wej(cid:258)ciowego mo(cid:285)na uzyska(cid:202) za po(cid:258)rednictwem potomnych obiektów FormController nadrz(cid:218)dnego obiektu FormController. Na przyk(cid:239)ad $scope.myform.myinput to obiekt FormController do wprowadzania tekstu. Aby powi(cid:200)zania stanu i walidacji mog(cid:239)y dzia(cid:239)a(cid:202), kontrolki wej(cid:258)ciowe musz(cid:200) by(cid:202) powi(cid:200)zane z dyrektyw(cid:200) ng-model. (cid:165)ledzenie stanu formularzy Kontrolki wej(cid:258)ciowe i formularze s(cid:200) dostarczane z w(cid:239)asnymi sterownikami. Framework An- gularJS (cid:258)ledzi stan zarówno indywidualnych kontrolek wej(cid:258)ciowych, jak i ca(cid:239)ego formularza, u(cid:285)ywaj(cid:200)c dychotomii czysty-brudny (ang. pristine-dirty). Stan „czysty” (ang. pristine) odpowiada sytuacji, w której kontrolki wej(cid:258)ciowe s(cid:200) ustawione na warto(cid:258)ci domy(cid:258)lne, natomiast stan „brud- ny” (ang. dirty) odnosi si(cid:218) do dowolnej operacji modyfikacji danych modelu powi(cid:200)zanych z kontrolkami wej(cid:258)ciowymi. Stan „czysty” ca(cid:239)ego formularza to wynik logicznej operacji AND na wszystkich stanach czystych kontrolek wej(cid:258)ciowych albo wynik operacji NOR dla wszystkich stanów brudnych. Zgodnie z odwrócon(cid:200) definicj(cid:200) stan „brudny” ca(cid:239)ego formularza reprezentuje wynik operacji OR wszystkich stanów brudnych albo wynik operacji NAND wszystkich stanów czystych. JSFiddle: http://jsfiddle.net/msfrisbie/trjfzdwc/ 171 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury Wymienione stany mog(cid:200) by(cid:202) u(cid:285)yte na kilka ró(cid:285)nych sposobów. Zarówno z elementami form , jak i input s(cid:200) zwi(cid:200)zane klasy CSS ng-pristine i ng-dirty, które s(cid:200) do nich automatycznie stosowane na podstawie stanu, w jakim znajduje si(cid:218) formularz. Te klasy CSS mog(cid:200) zosta(cid:202) u(cid:285)yte do nadania stylu kontrolkom wej(cid:258)ciowym na podstawie ich stanu, tak jak pokazano poni(cid:285)ej: form.ng-pristine { } input.ng-pristine { } form.ng-dirty { } input.ng-dirty { } Wszystkie egzemplarze klasy FormController oraz egzemplarze klasy ngModelController znaj- duj(cid:200)ce si(cid:218) wewn(cid:200)trz nich maj(cid:200) dost(cid:218)pne w(cid:239)a(cid:258)ciwo(cid:258)ci typu Boolean $pristine i $dirty. Mo(cid:285)na z nich skorzysta(cid:202) w logice biznesowej kontrolera albo do sterowania dzia(cid:239)aniami u(cid:285)ytkownika wewn(cid:200)trz formularza. W przyk(cid:239)adzie zamieszczonym poni(cid:285)ej wy(cid:258)wietla si(cid:218) komunikat Wprowad(cid:283) warto(cid:258)(cid:202) tak d(cid:239)ugo, a(cid:285) warto(cid:258)(cid:202) w polu wej(cid:258)ciowym zostanie zmodyfikowana. (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.$watch( myform.myinput.$pristine , function(newval) { $scope.isPristine = newval; }); }); (index.html) div ng-app= myApp div ng-controller= Ctrl form novalidate name= myform input name= myinput ng-model= formdata.myinput / /form div ng-show= isPristine Wprowad(cid:283) warto(cid:258)(cid:202) /div /div /div JSFiddle: http://jsfiddle.net/msfrisbie/unxbyun2/ 172 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem Mo(cid:285)na tak(cid:285)e wykry(cid:202), czy kontrolka wej(cid:258)ciowa jest w stanie czystym bezpo(cid:258)rednio w widoku, w czasie gdy obiekt formularza jest do(cid:239)(cid:200)czany do zakresu. (index.html) div ng-app= myApp div ng-controller= Ctrl form novalidate name= myform input name= myinput ng-model= formdata.myinput / div ng-show= myform.myinput.$pristine Wprowad(cid:283) warto(cid:258)(cid:202) /div /form /div /div JSFiddle: http://jsfiddle.net/msfrisbie/pr3L1e2b/ Mo(cid:285)na równie(cid:285) wymusi(cid:202) stan czysty lub brudny formularza lub kontrolki wej(cid:258)ciowej, u(cid:285)ywa- j(cid:200)c metod $setDirty() albo $setPristine(). Wykorzystanie tego sposobu nie uwzgl(cid:218)dnia ak- tualnych warto(cid:258)ci kontrolek wej(cid:258)ciowych w tym momencie. Jest to jedynie przes(cid:239)oni(cid:218)cie warto(cid:258)ci Boolean $pristine i $dirty oraz ustawienie odpowiadaj(cid:200)cych im klas CSS ng-pristine lub ng-dirty. Wywo(cid:239)anie tych metod b(cid:218)dzie propagowane do wszystkich formularzy nad- rz(cid:218)dnych. Walidowanie formularzy Oprócz dychotomii czysty-brudny, dla formularzy frameworka AngularJS obowi(cid:200)zuje równie(cid:285) dychotomia poprawny-niepoprawny. Do pól wej(cid:258)ciowych w formularzach mo(cid:285)na przypisywa(cid:202) regu(cid:239)y walidacji, które musz(cid:200) by(cid:202) spe(cid:239)nione, aby formularze by(cid:239)y poprawne. Framework AngularJS korzystaj(cid:200)c z dychotomii poprawny-niepoprawny (cid:258)ledzi poprawno(cid:258)(cid:202) zarówno indywidualnych pól wej(cid:258)ciowych, jak i ca(cid:239)ych formularzy. „Poprawny” odpowiada stanowi, w którym pola wej- (cid:258)ciowe spe(cid:239)niaj(cid:200) wszystkie przypisane do nich wymagania walidacji, natomiast „niepoprawny” odnosi si(cid:218) do pola wej(cid:258)ciowego, dla którego nie jest spe(cid:239)niona przynajmniej jedna regu(cid:239)a walida- cji. Stan „poprawny” ca(cid:239)ego formularza to wynik wykonania logicznej operacji AND stanów „poprawny” wszystkich kontrolek wej(cid:258)ciowych albo wynik operacji NOR stanów „niepoprawny” wszystkich kontrolek wej(cid:258)ciowych. Zgodnie z odwrócon(cid:200) definicj(cid:200) stan „niepoprawny” ca(cid:239)ego formularza reprezentuje wynik logicznej operacji OR wszystkich stanów „niepoprawny” albo wynik operacji NAND wszystkich stanów „poprawny”. JSFiddle: http://jsfiddle.net/msfrisbie/ejpsrfgz/ 173 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury Elementy form i input maj(cid:200) klasy CSS ng-valid i ng-invalid podobne do klas ng-pristine i ng-dirty, które s(cid:200) ustawiane automatycznie na podstawie stanu, w jakim znajduje si(cid:218) formularz. Te klasy CSS mo(cid:285)na wykorzysta(cid:202) do nadawania kontrolkom wej(cid:258)ciowym stylu na podstawie stanu. Oto przyk(cid:239)ad: form.ng-valid { } input.ng-valid { } form.ng-invalid { } input.ng-invalid { } Dla wszystkich wewn(cid:218)trznych egzemplarzy klas FormController i ngModelController dost(cid:218)pne s(cid:200) atrybuty typu Boolean $valid i $invalid. Mo(cid:285)na z nich skorzysta(cid:202) w logice biznesowej kontrolera albo do sterowania dzia(cid:239)aniami u(cid:285)ytkownika wewn(cid:200)trz formularza. W poni(cid:285)szym przyk(cid:239)adzie pokazano, jak wy(cid:258)wietli(cid:202) komunikat Pole wej(cid:258)ciowe nie mo(cid:285)e by(cid:202) puste w czasie, kiedy pole do wprowadzania danych jest puste: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.$watch( myform.myinput.$invalid , function(newval) { $scope.isInvalid = newval; }); }); (index.html) div ng-app= myApp div ng-controller= Ctrl form novalidate name= myform input name= myinput ng-model= formdata.myinput required / /form div ng-show= isInvalid Pole wej(cid:258)ciowe nie mo(cid:285)e by(cid:202) puste /div /div /div JSFiddle: http://jsfiddle.net/msfrisbie/40bdaey4/ 174 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem Alternatywnie, ze wzgl(cid:218)du na to, (cid:285)e obiekt formularza jest do(cid:239)(cid:200)czony do zakresu, mo(cid:285)liwe jest wykrycie bezpo(cid:258)rednio w widoku, czy pole wej(cid:258)ciowe jest prawid(cid:239)owe. (app.js) angular.module( myApp , []) .controller( Ctrl , function() {}); (index.html) div ng-app= myApp div ng-controller= Ctrl form novalidate name= myform input name= myinput ng-model= formdata.myinput required / div ng-show= myform.myinput.$pristine Pole wej(cid:258)ciowe nie mo(cid:285)e by(cid:202) puste /div /form /div /div JSFiddle: http://jsfiddle.net/msfrisbie/bc2hn05p/ Walidatory wbudowane i niestandardowe W frameworku AngularJS istniej(cid:200) nast(cid:218)puj(cid:200)ce wbudowane podstawowe walidatory: (cid:81) e-mail, (cid:81) max, (cid:81) maxlength, (cid:81) min, (cid:81) minlength, (cid:81) number, (cid:81) pattern, (cid:81) required, (cid:81) url. Chocia(cid:285) s(cid:200) one przydatne i w wi(cid:218)kszo(cid:258)ci nie wymagaj(cid:200) wyja(cid:258)nie(cid:241), to mo(cid:285)e si(cid:218) zdarzy(cid:202), (cid:285)e zajdzie potrzeba stworzenia niestandardowego walidatora. Aby to zrobi(cid:202), nale(cid:285)y zbudowa(cid:202) dyrektyw(cid:218), która b(cid:218)dzie obserwowa(cid:202) warto(cid:258)(cid:202) modelu odpowiadaj(cid:200)c(cid:200) temu polu wej(cid:258)ciowemu, przeprowadzi(cid:202) dla niej analiz(cid:218), a nast(cid:218)pnie ustawi(cid:202) poprawno(cid:258)(cid:202) tego pola, u(cid:285)ywaj(cid:200)c metody $setValidity(). 175 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury W ramach wydania 1.3 wprowadzono alternatywn(cid:200) metod(cid:218) tworzenia niestandardowych walidatorów formularzy. Wi(cid:218)cej informacji mo(cid:285)na znale(cid:283)(cid:202) w recepturze Tworzenie niestandardowych walidatorów formularzy i korzystanie z nich w rozdziale 9., „Co nowego w AngularJS 1.3?”. Poni(cid:285)ej pokazano sposób stworzenia niestandardowego walidatora, który sprawdza, czy w polu wej(cid:258)ciowym wprowadzono liczb(cid:218) pierwsz(cid:200): (app.js) angular.module( myApp , []) .directive( ensurePrime , function() { return { require: ngModel , link: function(scope, element, attrs, ctrl) { function isPrime(n) { if (n 2) { return false; } var m = Math.sqrt(n); for (var i=2; i =m; i++) { if (n i === 0) { return false; } } return true; } $scope.$watch(giganticObject, function() { ... if (isPrime(newval)) { ctrl.$setValidity( prime , true); } else { ctrl.$setValidity( prime , true); } }); } }; }); (index.html) div ng-app= myApp form novalidate name= myform input type= number ensure-prime name= myinput ng-model= formdata.myinput required / 176 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem /form div ng-show= myform.myinput.$pristine NAle(cid:285)y wprowadzi(cid:202) liczb(cid:218) pierwsz(cid:200) /div /div JSFiddle: http://jsfiddle.net/msfrisbie/7mhqvgcp/ Jak to dzia(cid:239)a? Formularze AngularJS w celu sprawdzenia stanu formularzy i stanu walidacji si(cid:218)gaj(cid:200) do ist- niej(cid:200)cej architektury wi(cid:200)zania danych. Egzemplarze klasy FormController powi(cid:200)zane z for- mularzem oraz pola wej(cid:258)ciowe znajduj(cid:200)ce si(cid:218) wewn(cid:200)trz tworz(cid:200) bardzo przyjemny, modu(cid:239)owy sposób zarz(cid:200)dzania przep(cid:239)ywem danych wewn(cid:200)trz formularza. Korzystanie z elementów select i dyrektywy ngOptions AngularJS dostarcza dyrektyw(cid:218) ngOptions, pozwalaj(cid:200)c(cid:200) na wype(cid:239)nianie w aplikacji elementów select . Chocia(cid:285) na pierwszy rzut oka wydaje si(cid:218) to trywialne, dyrektywa ngOptions wyko- rzystuje skomplikowany obiekt comprehension_expression, który pozwala wype(cid:239)ni(cid:202) rozwijan(cid:200) list(cid:218) na podstawie obiektów danych na kilka sposobów. Przygotuj si(cid:218) Za(cid:239)ó(cid:285)my, (cid:285)e aplikacja zawiera nast(cid:218)puj(cid:200)cy kod: (app.js) angular.module( myApp , []) .controller( Ctrl , function($scope) { $scope.players = [ { number: 17, name: Alshon , position: WR }, { number: 15, name: Brandon , position: WR 177 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury }, { number: 22, name: Matt , position: RB }, { number: 83, name: Martellus , position: TE }, { number: 6, name: Jay , position: QB } ]; $scope.team = { 3B : { number: 9, name: Brandon }, 2B : { number: 19, name: Marco }, 3B : { number: 48, name: Pablo }, C : { number: 28, name: Buster }, SS : { number: 35, name: Brandon } }; }); Jak to zrobi(cid:202)? Dyrektywa ngOptions pozwala na wype(cid:239)nienie elementu select zarówno na podstawie tablicy, jak i atrybutów obiektu. 178 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem Wype(cid:239)nianie na podstawie tablicy Obiekt comprehension_expression pozwala zdefiniowa(cid:202) sposób mapowania tablicy danych do zbioru tagów option wraz z tekstowym opisem i odpowiednimi warto(cid:258)ciami. (cid:146)atwiejsza implementacja polega na zdefiniowaniu tylko ci(cid:200)gu etykiety. W tym przypadku aplikacja do- my(cid:258)lnie ustawi warto(cid:258)(cid:202) option na ca(cid:239)y element tablicy, tak jak pokazano poni(cid:285)ej: (index.html) div ng-app= myApp div ng-controller= Ctrl !-- etykieta na warto(cid:286)(cid:252) w tablicy -- select ng-model= player ng-options= p.name for p in players /select /div /div Powy(cid:285)szy kod skompiluje si(cid:218) do postaci zamieszczonej poni(cid:285)ej (klasy CSS zwi(cid:200)zane z formu- larzami zosta(cid:239)y pomini(cid:218)te): select ng-model= player ng-options= player.name for player in players option value= ? selected= selected /option option value= 0 Alshon /option option value= 1 Brandon /option option value= 2 Matt /option option value= 3 Martellus /option option value= 4 Jay /option /select JSFiddle: http://jsfiddle.net/msfrisbie/vy62c575/ W tym przypadku warto(cid:258)ci poszczególnych opcji s(cid:200) indeksami tablicy odpowiadaj(cid:200)cymi po- szczególnym elementom. Poniewa(cid:285) model, do którego jest do(cid:239)(cid:200)czona aplikacja, nie jest zaini- cjowany do (cid:285)adnego z istniej(cid:200)cych elementów, framework AngularJS tymczasowo wstawi warto(cid:258)(cid:202) null na list(cid:218). W tym momencie pusta warto(cid:258)(cid:202) b(cid:218)dzie obci(cid:218)ta. W chwili dokonania wyboru model player zostanie przypisany do ca(cid:239)ego obiektu pod tym indeksem tablicy. Jawne definiowanie warto(cid:258)ci opcji Je(cid:285)eli nie chcemy, aby warto(cid:258)(cid:202) HTML option zosta(cid:239)a przypisana do indeksu tablicy, mo(cid:285)emy to przes(cid:239)oni(cid:202) za pomoc(cid:200) klauzuli track by, tak jak pokazano poni(cid:285)ej: 179 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury (index.html) div ng-app= myApp div ng-controller= Ctrl !-- etykieta na warto(cid:286)(cid:252) w tablicy -— select ng-model= player ng-options= p.name for p in players track by p.number /select /div /div Po skompilowaniu uzyskamy nast(cid:218)puj(cid:200)cy kod: select ng-model= player ng-options= p.name for p in players track by p.number option value= ? selected= selected /option option value= 17 Alshon /option option value= 15 Brandon /option option value= 22 Matt /option option value= 83 Martellus /option option value= 6 Jay /option /select JSFiddle: http://jsfiddle.net/msfrisbie/umehb407/ Dokonanie wyboru w dalszym ci(cid:200)gu spowoduje przypisanie odpowiedniego obiektu w tablicy do modelu player. Jawne definiowanie przypisania modelu opcji Je(cid:285)eli zamiast sztywnego ustawiania elementów option na atrybut number ka(cid:285)dego elementu tablicy chcemy mie(cid:202) jawn(cid:200) kontrol(cid:218) nad warto(cid:258)ci(cid:200) ka(cid:285)dego elementu option , mo(cid:285)emy sko- rzysta(cid:202) z nast(cid:218)puj(cid:200)cego sposobu: (index.html) div ng-app= myApp div ng-controller= Ctrl !-- etykieta na warto(cid:286)(cid:252) w tablicy -- select ng-model= player ng-options= p.number as p.name for p in players /select /div /div Powy(cid:285)szy kod skompiluje si(cid:218) do postaci zamieszczonej poni(cid:285)ej (klasy CSS zwi(cid:200)zane z formu- larzami zosta(cid:239)y pomini(cid:218)te): 180 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem select ng-model= player ng-options= p.number as p.name for p in players option value= ? selected= selected /option option value= 17 Alshon /option option value= 15 Brandon /option option value= 22 Matt /option option value= 83 Martellus /option option value= 6 Jay /option /select JSFiddle: http://jsfiddle.net/msfrisbie/jtsz46cp/ Jednak teraz, gdy zostanie wybrany element option , do modelu player zostanie przypisany tylko atrybut number odpowiedniego obiektu. Implementacja grup opcji Aby skorzysta(cid:202) z mo(cid:285)liwo(cid:258)ci grupowania dla elementów select , mo(cid:285)emy doda(cid:202) klauzul(cid:218) group by, tak jak pokazano poni(cid:285)ej: (index.html) div ng-app= myApp div ng-controller= Ctrl !-- etykieta na warto(cid:286)(cid:252) w tablicy -— select ng-model= player ng-options= p.name group by p.position for p in players /select /div /div Powy(cid:285)szy kod skompiluje si(cid:218) do nast(cid:218)puj(cid:200)cej postaci: select ng-model= player ng-options= p.name group by p.position for p in players option value= ? selected= selected /option optgroup label= WR option value= 0 Alshon /option option value= 1 Brandon /option /optgroup optgroup label= RB option value= 2 Matt /option /optgroup optgroup label= TE option value= 3 Martellus /option /optgroup optgroup label= QB 181 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury option value= 4 Jay /option /optgroup /select JSFiddle: http://jsfiddle.net/msfrisbie/2d6mdt9m/ Opcje null Aby zezwoli(cid:202) na opcje null, mo(cid:285)emy jawnie je zdefiniowa(cid:202) wewn(cid:200)trz znacznika select , tak jak pokazano poni(cid:285)ej: (index.html) select ng-model= player ng-options= comprehension_expression option value= Wybierz gracza /option /select Wype(cid:239)nianie na podstawie obiektu Elementy select korzystaj(cid:200)ce z dyrektywy ngOptions mog(cid:200) równie(cid:285) zosta(cid:202) wype(cid:239)nione atrybutami obiektu. Mechanizm ten dzia(cid:239)a podobnie do sposobu polegaj(cid:200)cego na przetwarza- niu tablicy danych. Jedyna ró(cid:285)nica polega na konieczno(cid:258)ci zdefiniowania par klucz-warto(cid:258)(cid:202) w obiekcie, które b(cid:218)d(cid:200) wykorzystane do wygenerowania listy elementów option . W prostym przypadku w celu zmapowania w(cid:239)a(cid:258)ciwo(cid:258)ci number obiektu value na ca(cid:239)y obiekt value mo(cid:285)na doda(cid:202) nast(cid:218)puj(cid:200)cy kod: (index.html) div ng-app= myApp div ng-controller= Ctrl !-- etykieta na warto(cid:286)(cid:252) w tablicy -— select ng-model= player ng-options= p.number for (pos, p) in team /select /div /div Po skompilowaniu uzyskamy nast(cid:218)puj(cid:200)cy kod: select ng-model= player ng-options= p.number for (pos, p) in team option value= ? selected= selected /option option value= 1B 9 /option option value= 2B 19 /option option value= 3B 48 /option option value= C 28 /option option value= SS 35 /option /select 182 Poleć książkęKup książkę Rozdzia(cid:225) 5. • Praca z zakresami i modelem JSFiddle: http://jsfiddle.net/msfrisbie/zofojs7n/ Domy(cid:258)lnie warto(cid:258)ciami option s(cid:200) (cid:239)a(cid:241)cuchy klucza, ale model player nadal b(cid:218)dzie przypisany do ca(cid:239)ego obiektu, do którego odnosi si(cid:218) klucz. Jawne definiowanie warto(cid:258)ci opcji Je(cid:285)eli nie chcemy, aby do warto(cid:258)ci elementu HTML option by(cid:239)a przypisana w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) klucza, mo(cid:285)emy to przes(cid:239)oni(cid:202) za pomoc(cid:200) klauzuli select as: (index.html) div ng-app= myApp div ng-controller= Ctrl !-- etykieta na warto(cid:286)(cid:252) w tablicy -— select ng-model= player ng-options= p.number as p.name for (pos, p) in team /select /div /div Po skompilowaniu uzyskamy nast(cid:218)puj(cid:200)cy kod: select ng-model= player ng-options= p.number as p.name for (pos, p) in team option value= ? selected= selected /option option value= 1B Brandon /option option value= 2B Marco /option option value= 3B Pablo /option option value= C Buster /option option value= SS Brandon /option /select JSFiddle: http://jsfiddle.net/msfrisbie/ssLzvtaf/ Teraz, kiedy zostanie wybrany element option , do modelu player zostanie przypisana tylko w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) number odpowiedniego obiektu. Jak to dzia(cid:239)a? Dyrektywa ngOptions po prostu analizuje przekazany do niej element typu wyliczeniowego na fragmenty, które mog(cid:200) zosta(cid:202) przekszta(cid:239)cone na tagi option . 183 Poleć książkęKup książkę AngularJS. Tworzenie aplikacji webowych. Receptury Co dalej? Wewn(cid:200)trz znacznika select , ze wzgl(cid:218)dów wydajno(cid:258)ciowych, preferowane jest u(cid:285)ycie dy- rektywy ngOptions zamiast ngRepeat. W przypadku warto(cid:258)ci w rozwijanych kontrolkach wi(cid:200)zanie danych nie jest jak konieczne, dlatego implementacja bazuj(cid:200)ca na ngRepeat, która musi przegl(cid:200)- da(cid:202) wiele warto(cid:258)ci w kolekcji, wprowadza w aplikacji niepotrzebny narzut wi(cid:200)zania danych. Budowanie magistrali zdarze(cid:241) W zale(cid:285)no(cid:258)ci od przeznaczenia aplikacji czasami mo(cid:285)e pojawi(cid:202) si(cid:218) potrzeba skorzystania z architektury publikacja-subskrypcja (od ang. publish-subscribe — pub-sub), która pozwala zrealizowa(cid:202) kilka funkcji. Framework AngularJS dostarcza w(cid:239)a(cid:258)ciwego zestawu narz(cid:218)dzi, który pozwala zaimplementowa(cid:202) t(cid:218) architektur(cid:218). Jednak by zapobiec obni(cid:285)eniu wydajno(cid:258)ci i utrzyma(cid:202) dobr(cid:200) organizacj(cid:218) aplikacji, trzeba wzi(cid:200)(cid:202) pod uwag(cid:218) pewne sprawy. Dawniej u(cid:285)ywanie us(cid:239)ugi $broadcast z poziomu zakresu zawieraj(cid:200)cego bardzo du(cid:285)(cid:200) liczb(cid:218) zakresów potomnych, ze wzgl(cid:218)du na du(cid:285)(cid:200) liczb(cid:218) potencjalnych s(cid:239)uchaczy, którzy potrzebowali obs(cid:239)u(cid:285)enia, wnosi(cid:239)o znacz(cid:200)ce obni(cid:285)enie wydajno(cid:258)ci. W wydaniu AngularJS 1.2.7 wprowadzono optymalizacj(cid:218) us(cid:239)ugi $broadcast. Polega ona na ograniczeniu zasi(cid:218)gu zdarzenia tylko do tych zakresów, które nas(cid:239)uchuj(cid:200) tego zdarzenia. Dzi(cid:218)ki wprowadzonemu usprawnieniu mo(cid:285)na swo- bodniej korzysta(cid:202) z us(cid:239)ugi $broadcast w aplikacji. Nadal jednak istnieje luka do wype(cid:239)nienia w celu obs(cid:239)ugi aplikacji us(cid:239)ugowych wymagaj(cid:200)cych architektury pub-sub. Mówi(cid:200)c prosto, aplika- cja powinna by(cid:202) w stanie nadawa(cid:202) zdarzenie do subskrybentów bez konieczno(cid:258)ci korzystania z metody $rootScope.$broadcast(). Przygotuj si(cid:218) Przypu(cid:258)(cid:202)my, (cid:285)e mamy aplikacj(cid:218) zawieraj(cid:200)c(cid:200) wiele ró(cid:285)ni(cid:200)cych si(cid:218) od siebie zakresów, które musz(cid:200) zareagowa(cid:202) na pojedyncze zdarzenie, tak jak pokazano poni(cid:285)ej: (app.js) angular.module( pubSubApp ,[]) .controller( Ctrl ,function($scope) {}) .directive( myDir ,function() { return { scope: {}, link:
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

AngularJS. Tworzenie aplikacji webowych. Receptury
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ą: