ngular, cz. II 1/30 Angular, cz. II Tworzenie serwisów Web 2.0 dr inż. Robert Perliński rperlinski@icis.pcz.pl Politechnika Częstochowska Instytut Informatyki Teoretycznej i Stosowanej 14 marca 2016
Angular, cz. II 2/30 Plan prezentacji 1 Dyrektywy ng-include własne dyrektywy 2 Usługi $scope $http
Angular, cz. II 3/30 AngularJS Strona projektu: https://angularjs.org/ Dokumentacja: https://docs.angularjs.org/api Tutorial: https://docs.angularjs.org/tutorial Przewodnik dla developerów: https://docs.angularjs.org/guide Kurs na CodeSchool: http://angular.codeschool.com/
Angular, cz. II 4/30 Dyrektywy, ng-include Dyrektywa ng-include: pozwala zastąpić wielokrotnie powtarzający się fragment kodu pozwala też na podzielenie większego kodu na mniejsze części fragment kodu umieszczamy w osobnym pliku html i dołączamy ng-include może być wykorzystana jako dyrektywa użytkownika (atrybut src): <ng-include src="">... </ng-include> albo jako atrybut w dowolnym znaczniku: <ANY ng-include="">... </ANY> Angular napotykając ng-include wywołuje zapytanie AJAX. Najpierw wczytywana jest cała strona, a następnie asynchronicznie dołączane jej fragmenty.
Angular, cz. II 5/30 Dyrektywy, ng-include, przykład Zawartość pliku index.html:... <h3> {{produkt.nazwa}} <em class="pull-right">{{produkt.cena currency}}</em> </h3>... Zawartość index.html po zmianie: (dodatkowe apostrofy wewnątrz cudzysłowu - ng-include oczekuje zmiennych)... <h3 ng-include=" produkt-tytul.html "></h3> <h4 ng-include="sklep.nazwapliku"></h4>... Zawartość produkt-tytul.html {{produkt.nazwa}} <em class="pull-right">{{produkt.cena currency}}</em>
Angular, cz. II 6/30 Własne dyrektywy (ang. custom directives) Dyrektywa ng-include działa ale... Preferowany sposób używania szablonów to tworzenie własnych dyrektyw. W dyrektywach użytkownika można używać dyrektyw wbudowanych, np. ng-show. Do własnych dyrektyw można, a nawet warto dołączać kontrolery. Własna dyrektywa może wyglądać np.: <produkt-tytul></produkt-tytul> <h2 produkt-tytul></h2> Własne dyrektywy do działania wymagają jednak dodatkowego kodu. Dlaczego więc je używamy?
ngular, cz. II 6/30 Własne dyrektywy (ang. custom directives) Dyrektywa ng-include działa ale... Preferowany sposób używania szablonów to tworzenie własnych dyrektyw. W dyrektywach użytkownika można używać dyrektyw wbudowanych, np. ng-show. Do własnych dyrektyw można, a nawet warto dołączać kontrolery. Własna dyrektywa może wyglądać np.: <produkt-tytul></produkt-tytul> <h2 produkt-tytul></h2> Własne dyrektywy do działania wymagają jednak dodatkowego kodu. Dlaczego więc je używamy? Pozwalają pisać kod html, który wyraża zachowanie naszej aplikacji.
Angular, cz. II 7/30 Własne dyrektywy wyrażają zachowanie aplikacji Zwykle kod html pokazuje tylko strukturę, nie mówi nic o zachowaniu strony. Własne dyrektywy pozwalają na wyrażenie tego, co dany fragment szablonu robi (ekspresyjność, wyrazistość). <aside class="col-sm-3"> <ksiazka-okladka></ksiazka-okladka> <h4><ksiazka-ranking></ksiazka-ranking></h4> </aside> <div class="col-sm-9"> <h3><ksiazka-tytul></ksiazka-tytul></h3> <ksiazka-autorzy></ksiazka-autorzy> <ksiazka-opis></ksiazka-opis> <ksiazka-rodzaj></ksiazka-gatunek> </div>
Angular, cz. II 8/30 Własne dyrektywy - rodzaje Dyrektywy rozwijające, włączające zdefiniowane szablony - najprostszy rodzaj. Definiuje się własny znacznik albo atrybut, który pokazuje albo rozwija szablon. Szablony takie mogą też zawierać kontroler czyli jakąś funkcjonalność jeśli jest potrzebna. Dyrektywy do wyrażania złożonych interfejsów użytkownika. Dyrektywy do wywołujące zdarzenia i rejestrujące uchwyty do zdarzeń. Dyrektywy pozwalające na wykorzystanie zdefiniowanych komponentów.
Angular, cz. II 9/30 Definiowanie własnej dyrektywy I Dyrektywa <produkt-tytul></produkt-tytul> wymaga następującej definicji: app.directive( produkttytul, function(){ return { restrict: E, templateurl: produkt-tytul.html }; }); app.directive(); - dyrektywy w Angular. Pierwszy argument to nazwa dyrektywy. Myślinik w nazwie w HTML zmienia się na dużą literę w nazwie JavaScript. Drugi argument to anonimowa funkcja, ktora zwraca obiekt definiujący dyrektywę (ang. directive definition object). Obiekt definiujący dyrektywę to, najprościej mówiąc, konfiguracja określająca jak dyrektywa ma działać.
Angular, cz. II 10/30 Definiowanie własnej dyrektywy II Dyrektywa <produkt-tytul></produkt-tytul> wymaga następującej definicji: app.directive( produkttytul, function(){ return { restrict: E, templateurl: produkt-tytul.html }; }); Dwie opcje konfiguracyjne: restrict - określa typ dyrektywy. E od słowa Element czyli dyrektywa będzie nowym elementem HTML. templateurl - zawiera URL szablonu, który chcemy pozwiązać z definiowaną dyrektywą. Dyrektywę definiujemy wewnątrz modułu, np. w pliku app.js. Unikamy samoamkniętych znaczników: <produkty-tytul/> - niektóre przeglądarki źle współpracują z dowolnymi samozamkniętymi znacznikami.
Angular, cz. II 11/30 Definiowanie własnej dyrektywy III Definicja dyrektywy będącej atrybutem znacznika Dyrektywa <h3 produkt-tytul></h3> wymaga następującej definicji: app.directive( produkttytul, function(){ return { restrict: A, templateurl: produkt-tytul.html }; }); restrict - określa typ dyrektywy. A od słowa Attribute czyli dyrektywa będzie atrybutem elementu HTML. Po załadowaniu kod może być następujący: <h3 class="ng-binding" produkt-tytul="">aparat fotograficzny <em class="pull-right ng-binding">458,99 zł</em> </h3>
Angular, cz. II 12/30 Własne dyrektywy zawierające kontroler I Fragment strony HTML korzystający z kontrolera przenosimy do osobnego pliku HTML. Fragment związany z panelami produktów na stronie: <div ng-controller="panelcontroller as panel">... </div> Zamieniamy na: <produkty-panel ng-controller="panelcontroller as panel">... </produkty-panel> Tworzymy dyrektywę: app.directive( produktypanel, function(){ return { restrict: E, templateurl: produkty-panel.html, }; }); Przydało by się przenieść kontroler do utworzonej dyrektywy...
Angular, cz. II 13/30 Własne dyrektywy zawierające kontroler II Obiekt definiujący dyrektywę zawiera dwie dodatkowe opcje konfiguracyjne: controller - określa funkcjonalność kontrolera przypisanego do dyrektywy. Tutaj przenosimy funkcjonalność kontrolera, który chcemy związać z definiowaną dyrektywą. controlleras - określa alias, jakim będziemy się podługiwać w obszarze zdefiniowanej dyrektywy. W naszym przypadku będzie to: controlleras: panel. app.directive( produktypanel, function(){ return {... controller: function() {... }, controlleras: panel, }; }); Wygodnie jest mieć funkcjonalność razem ze zdefiniowaną dyrektywą.
Angular, cz. II 14/30 Własne dyrektywy zawierające kontroler III Całość dyrektywy przedstawia się następująco: app.directive( produktypanel, function(){ return { restrict: E, templateurl: produkty-panel.html, controller: function() { this.tab = 1; this.settab = function(stab) { this.tab = stab; }; this.isselected = function(stab) { return this.tab === stab; }; }, controlleras: panel, }; });
Angular, cz. II 15/30 Moduły Kiedy nasz kod robi się za duży warto podzielić go na moduły. Tworzymy nowy plik, np. produkty.js, w którym umieszczamy kod: (function(){ var app = angular.module( sklep-produkty, [ ]); app.directive( produkttytul, function(){... }); app.directive( produktypanel, function(){... }); app.directive( galeria, function(){... }); })(); angular.module(); - definicja nowego modułu. sklep-produkty to nazwa modułu. W nawiasach kwadratowych są zależności. Ponowne użycie zmiennej app (taka sama nazwa w głównym module aplikacji) nie stwarza problemu - obie zmienne mają zasięg ograniczony wewnątrz modułów.
Angular, cz. II 16/30 Moduły - zależności W głównym module aplikacji dodajemy utworzony moduł: (function(){ var app = angular.module( sklep, [ sklep-produkty ]); })(); app.controller( StoreController, function(){... });... Dodatkowo należy dołączyć plik nowego modułu do strony: <script type="text/javascript" src="produkty.js"></script>
Angular, cz. II 17/30 Usługi Usługi pozwalają nam m.in. na pobranie danych z zewnętrznego źródła. Lista produktów w naszych przykładach powinna być pobierana z jakiegoś API, w naszym przypadku JSON. Produkty wykorzystywane w przykładach dostępne poprzez stronę http://www.json-generator.com/api/json/get/binywejauw?indent=2 Zawartość: [ { "komentarze": [ { "autor": "felek77@domena.pl", "tresc": "Bardzo fajny aparat. Uwielbiam go!", "ocena": 5 },... ]
Angular, cz. II 18/30 Usługi w Angular Angular posiada wiele wbudowanych usług. Usługi pozwalają dodać do naszego kontrolera dodatkową funkcjonalność. Wszystkie usługi wbudowane w Angular zaczynają się od znaku $. Usługi pozwalają na: Pobranie danych w postaci JSON z usługi internetowej (web service) przez usługę $http. Zapis logów do konsoli JavaScript za pośrednictwem usługi $log. Filtrowanie zawartości tablic za pomocą usługi $filter.
Angular, cz. II 19/30 Usługa $scope Usługa $scope: ma specjalne znaczenie, odróżnia się od innych usług, służy do udostępniania danych i funkcji widokom, udostępnianie odbywa się w kontrolerze. Jeśli chcemy żeby widoki miały dostęp do całego modelu to można przypisać do jakiejś właściwości obiektu $scope cały model, np.: $scope.lista = model; Dwa rodzaje dostępu do danych modelu w widoku: obiekt $scope, wykorzystanie aliasu kontrolera.
Angular, cz. II 20/30 Dane w widoku - wykorzystanie $scope Wykorzystanie usługi $scope w kontrolerze w funkcji kontrolera jest parametr $scope, obiekt $scope udostępni dane i funkcje do widoku app.controller( HelloController, function($scope) { $scope.produkt = ciastko; }); var ciastko = { nazwa: Ciasteczka, cena: 2.95, opis: Smaczne i zdrowe } Wykorzystanie właściwości produkt obiektu $scope w widoku: <div ng-controller="hellocontroller"> <h3>{{produkt.nazwa}}</h3> <code>{{produkt.cena currency}}</code> <p>{{produkt.opis}}</p> </div>
Angular, cz. II 21/30 Dane w widoku - wykorzystanie aliasu Kontroler bez obiektu $scope w funkcji kontrolera nie ma przekazanego żadnego parametru, w dołączeniu kontrolera w widoku musi być użyty alias app.controller( HelloController, function() { this.produkt = ciastko; }); var ciastko = { nazwa: Ciasteczka, cena: 2.95, opis: Smaczne i zdrowe } Wykorzystanie danych modelu w widoku za pomocą aliasu hello: <div ng-controller="hellocontroller as hello"> <h3>{{hello.produkt.nazwa}}</h3> <code>{{hello.produkt.cena currency}}</code> <p>{{hello.produkt.opis}}</p> </div>
Angular, cz. II 22/30 Usługa $http Usługa $http pozwala nam wykonać asynchroniczne zapytanie do serwera. Można użyć $http jako funkcji z obiektem zawierającym opcje: $http({ method: GET, url: /produkty.json }); Można też użyć jednej z metod usługi $http: $http.get( /produkty.json, { apikey: myapikey }); Obie metody zwracają objekt Promise. Na takim obiekcie można wykonać funkcje zwrotne.success() albo.error(). Jeśli usługa $http pobiera JSON to wynik zostanie automatycznie przekształcony do objektu czy tablicy JavaScript.
Angular, cz. II 23/30 Usługa $http Kontroler musi poinformować Angular jakich usług potrzebuje. W tym celu używamy takich dziwnych wyrażeń tablicowych app.controller( PrzykladowyKontroler, [ $http, function($http){ } ]); $http oznacza nazwę usługi; w tablicy najpierw określamy nazwy usług. $http to usługa przekazywana jako argument do funkcji kontrolera; w ten sposób można użyć $http wewnątrz kontrolera. Taki sposób przekazywania usług potrzebnych kontrolerowi nazywa się wstrzykowaniem zależności (ang. dependency injection). Injector przekazuje usługi wymagane przez kontroler jako argumenty. Stąd wstrzykiwanie zależności, bo injector wstrzykuje zależnośći (w tym przypadku usługi) do funkcji kontrolera jako argumenty. Wyrażenie w przypadku dwóch usług: app.controller( JakisKontroler, [ $http, $log, function($http, $log){ } ]);
Angular, cz. II 24/30 Usługa $http - przykład Przykład wykorzystania usługi $http w kontrolerze z pobraniem listy produktów przy wykorzystaniu funkcji zwrotniej success(). (function(){ var app = angular.module( sklep, [ sklep-produkty ]); }]); })(); app.controller( StoreController, [ $http, function($http){ this.produkty =??? $http.get( /produkty.json ).success(function(data){??? = data; }); Lista produktów jest zwrócona w obiekcie data. Dane należy przypisać do this.produkty ale nie możemy się odwołać do tych danych wewnątrz funkcji zwrotnej. this wewnątrz funkcji zwrotnej wskazuje na usługę $http. Więc?
Angular, cz. II 25/30 Usługa $http - przykład Przykład wykorzystania usługi $http w kontrolerze z pobraniem listy produktów przy wykorzystaniu funkcji zwrotniej success(). (function(){ var app = angular.module( sklep, [ sklep-produkty ]); }]); })(); app.controller( StoreController, [ $http, function($http){ var sklep = this; $http.get( /produkty.json ).success(function(data){ sklep.produkty = data; }); Lista produktów jest zwrócona w obiekcie data. Dane należy przypisać do this.produkty ale nie możemy się odwołać do tych danych wewnątrz funkcji zwrotnej. this wewnątrz funkcji zwrotnej wskazuje na usługę $http. Więc? Użyjemy zmiennej pomocniczej.
Angular, cz. II 26/30 Usługa $http - przykład Wykonanie zapytania asynchronicznego i zwrócenie wyniku może zająć jakiś czas. Strona nie będzie na to czekać i może się załadować bez listy produktów. Dobrym pomysłem będzie wstępne zainicjowanie zmiennej: sklep.produkty = [ ];
Angular, cz. II 27/30 Usługa $http + $scope - przykład Przykład wykorzystania usługi $http w kontrolerze z pobraniem listy osób z API, wykorzystanie funkcji zwrotnych success() oraz error(). (function(){ var app = angular.module( formularz, [ ]); app.controller( FormularzController, [ $scope, $http, function($scope,$http){ $http.get( https://przyklad.com/students ).success(function(data){ $scope.users = data; }).error(function(){ alert("error"); }); }]); })();
Angular, cz. II 28/30 Usługa $http.post - przykład Przykład wykorzystania usługi $http w kontrolerze z pobraniem listy osób z API, wykorzystanie funkcji zwrotnych success() oraz error(). (function(){... $http.post( https://przyklad.com/students, { "name":"jan", "surname":"nowicki", "age": 19 }).success(function(data){ alert("ok"); }).error(function(){ alert("error"); }); }]);... })();
Angular, cz. II 29/30 Usługa $http - dodatkowa funkcjonalność Poza metodą get() usługa $http zawiera jeszcze post(), put(), delete(),... $http.post( /sciezka/do/zasobow.json, { param: value }); $http.delete( /sciezka/do/zasobow.json ); Można również używać dowolnych innych metod usługi $http korzystając z obiektów z konfiguracją: $http({ method: OPTIONS, url: /sciezka/do/zasobow.json }); $http({ method: PATCH, url: /sciezka/do/zasobow.json }); $http({ method: TRACE, url: /sciezka/do/zasobow.json });
Angular, cz. II 30/30 Warto zobaczyć https://egghead.io/ - Kursy video dla AngularJS, React, D3 i innych kluczowych technologi internetowych. https://thinkster.io/ - Nauka nowoczesnych technologii internetowych, również zawiera filmy video https://kapeli.com/dash - Dokumentacja offline do bardzo wielu API technologi internetowych - warto pobrać!