CommitUniversity AngularJSAdvanced Andrea Vallotti

770 views
515 views

Published on

Andrea Vallotti presenta il workshop di CommitUniversity in AngularJS Advanced.
17 Luglio- Cinema di Sesto Fiorentino

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
770
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
25
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • priority è un numero, le direttive con priority maggiore vengono eseguite prima
    a parità di priority l’ordine è indeterminato
    priority di default è zero, alcune direttive che la cambiano sono: ng-disabled (100), ng-controller (500), ng-include (400), etc.
    terminal deve essere usato in congiunzione con priority
    require è ideale per la comunicazione tra direttive, che vedremo dopo, e possibile specificare una o più direttive (utilizzando un array). ? vuol dire che è opzionale, ^ vuol dire che la direttiva può essere su un elemento contenitore. Esempio menuDirective.js
  • la costruzione è invocata una volta sola durante il ciclo di vita dell’applicazione. Volendo far vedere il codice della slide #5 per far capite cos’è la costruzione
    scope e controller vengono creati solo se necessario;
    pre-linking → link allo scope prima della compilazione/linking dei figli
    post-linking → link allo scope dopo la compilazione/linking dei figli
    Direttive con priority maggiore vengono compilate per prime. Le funzioni di pre-link sono invocate nello stesso ordine mentre le funzioni di post-link vengono eseguite in ordine inverso;
  • Le direttive di default condividono lo scope del controller che le contiene
    true → se ci sono più direttive sullo stesso elemento che richiedono un nuovo scope con true allora AngularJS ne crea uno solo condiviso fra tutte
    deriva prototipicamente
    gli scope isolati sono scope che non partecipano alla normale eriditarietà prototipale degli scope di AngularJS
    uno scope isolato “vuoto” non contiene nulla se non ciò che ci viene messo dalla direttiva
  • gli scope isolati sono fondamentali per evitare che una direttiva possa interferire in alcun modo con il comportamento del controller o di altre direttive
    il valore di un attributo del DOM è sicuramente una stringa quindi il binding @darà sempre una stringa
    con il binding = il ? serve per dire che non è obbligatorio che l’attributo ci sia, di default è obbligatorio
    il binding & è perfetto stabilire una comunicazione fra direttiva e controller (nel verso opposto basta usare un binding :-) ). Vedi ui-bootstrap.js riga 2876

    VEDERE ESEMPIO LIVE SUL BROWSER
  • ideali per concentrare tutta la logica della direttiva e per contenere variabili che non devono essere esposte sullo scope per il binding
    $transclude è la stessa funzione che viene passata ai metodi di link, dato che non è consigliabile manipolare il DOM dal controller meglio non usarla
  • scope: è lo scope della direttiva (lo stesso del controller)
    iElement: è [il clone] del template
    iAttrs: è la lista “normalizzata” (cioè con i nomi in camel case) degli attributi presenti sull’elemento. E’ condiviso da tutte le direttive presenti su un elemento
    controller: è il controller della direttiva o una lista di controller se è stato utilizzata l’opzione require
    transcludeFn: è una funzione che consente di clonare e linkare il template per poi inserirlo nel DOM
    Direttive con priority maggiore vengono compilate per prime. Le funzioni di pre-link sono invocate nello stesso ordine mentre le funzioni di post-link vengono eseguite in ordine inverso;
    pre: dato che viene eseguita prima che i figli siano stati linkati è meglio evitare di manipolare il DOM. Deve essere usata solo per lavori preparatori o attività che non riguardano il DOM ma che comunque sono relative all’istanza specifico del DOM e non al template. E.g. direttiva form in angular.js alla riga 16345
  • eseguita dopo che il template è stato clonato
    esempio completo vedere cmswSpinnerDirective.js
  • in questo esempio è stato utilizzato anche l’attributo replace per sostituire il template della direttiva al posto dell’HTML originale
    il contenuto di una direttiva che ha transclude a true non fa riferimento allo scope della direttiva (anche se vi è contenuto nell’albero HTML) ma fa riferimento allo scope subito fuori dalla direttiva
  • Direttive con priority maggiore vengono compilate per prime. Le funzioni di pre-link sono invocate nello stesso ordine mentre le funzioni di post-link vengono eseguite in ordine inverso;
    vedere come esempio ngRepeat in angular.js alla riga 20393 - 20404
  • della funzione/oggetto di link se ne parla dopo
    migliora le performance perché se la nostra direttiva è utilizzata insieme, ad esempio, ad ng-repeat le operazione fatte nella funzione compile verranno effettuate una volta sola
    ngCloak si autoelimina dal proprio template nella funzione compile (angular.js riga 18624)
    se viene dichiarata la funzione compile non può essere dichiarata la funzione/oggetto link, quest’ultimo deve essere ritornato eventualmente dalla funzione compile
    Direttive con priority maggiore vengono compilate per prime. Le funzioni di pre-link sono invocate nello stesso ordine mentre le funzioni di post-link vengono eseguite in ordine inverso
  • CommitUniversity AngularJSAdvanced Andrea Vallotti

    1. 1. AngularJS direttive, testing e organizzazione @AndreaVallotti
    2. 2. AngularJS Advanced 17.07.2014 Alcune indicazioni… Potete scaricare i sorgenti da: http://localhost/AdvancedAngularBackend/ClientStandalon e.zip Potete collegarvi ai servizi usando: applicationUrls.baseUrl = 'http://localhost/AdvancedAngularBackend/'
    3. 3. AngularJS Advanced 17.07.2014 Riepilogo ● AngularJS ● Direttive ● Testing (Unit) ● Gestione delle dipendenze ● Mettiamo tutto insieme ● Q&A
    4. 4. AngularJS Advanced 17.07.2014 AngularJS ● AngularJS ● Direttive ● Testing (Unit) ● Gestione delle dipendenze ● Mettiamo tutto insieme ● Q&A
    5. 5. AngularJS Advanced 17.07.2014 AngularJS - Generale E’ un framework JavaScript: ● per lo sviluppo di applicazioni Web in modalità Single Page Application ● “forza” l’uso del pattern MVC ● implementa il two-way data-binding ● pensato per facilitare il test: o separazione delle competenze o dependency injection o mock del back end
    6. 6. AngularJS Advanced 17.07.2014 AngularJS - Anatomia <body ng-app=”ngCommitUniversity”> ... <div ng-controller="homeController"> ... <div cmsw-spinner="loadingTracker.active()" class="fixedHeight" spinner-options="{direction: -1, length: 50}"> ... <span ng-show="username" ng-bind="'Ciao ' + username + '!'"></span> </div>
    7. 7. AngularJS Advanced 17.07.2014 Direttive ● AngularJS ● Direttive ● Testing (Unit) ● Gestione delle dipendenze ● Mettiamo tutto insieme ● Q&A
    8. 8. AngularJS Advanced 17.07.2014 Direttive - Definizione //directives = angular.module('…', [ … ]); directives.directive('cmswSpinner', function () { return { // descrittore della direttiva }; }); //<div cmsw-spinner … Forme possibili: data-cmsw-spinner, x-cmsw-spinner, cmsw-spinner, cmsw_spinner, cmsw:spinner
    9. 9. AngularJS Advanced 17.07.2014 Direttive - Definizione ● restrict - definisce le modalità di utilizzo ammesse (e.g. restrict: ‘EA’) ● template - inline HTML template ● templateUrl - url per scaricare il template della direttiva tramite richiesta ajax ● replace - definisce se sostituire o appendere il template all’elemento originale
    10. 10. AngularJS Advanced 17.07.2014 Direttive - Definizione ● priority - definisce l’ordine di “esecuzione” delle direttive ● terminal - indica se il processo di compilazione deve terminare alla direttiva corrente ● require - specifica se è necessario utilizzare altre direttive: [?][^]directive
    11. 11. AngularJS Advanced 17.07.2014 Direttive - ciclo di vita 1. costruzione 2. compilazione del template 3. *creazione dello scope e del controller 4. *pre-linking 5. ricorsione sui figli 6. post-linking
    12. 12. AngularJS Advanced 17.07.2014 Direttive - scope scope: false | true | { … } ● false - è il default, la direttiva condivide lo scope del controllore che la contiene ● true - viene creato uno scope per la direttiva che “deriva” dallo scope contenitore ● { … } - viene creato uno scope isolato
    13. 13. AngularJS Advanced 17.07.2014 ● fondamentali per: separazione e riusabilità ● permettono di definire dei collegamenti con il mondo esterno: o @[attr] - collegamento monodirezionale con il valore di un attributo del DOM o =[?][attr] - collegamento bidirezionale o &[attr] - esecuzione di un espressione nello scope contenitore Direttive - scope isolati
    14. 14. AngularJS Advanced 17.07.2014 Direttive - controller ● si dichiarano come i controller “normali” ● iniettabile con: o qualunque servizio disponibile nell’applicazione o servizi specifici: $scope, $element, $attrs, $transclude ● logica e varibili “locali” ● no manipolazione del DOM ● opzionale
    15. 15. AngularJS Advanced 17.07.2014 Direttive - link link: function (scope, iElement, iAttrs, [controller], [transcludeFn]) { ... } oppure: link: { pre: function ( … ) { ... } post: function ( … ) { ... } }
    16. 16. AngularJS Advanced 17.07.2014 Direttive - link ● è la funzione principale ● nel 80% dei casi non serve altro ● manipolazione del DOM ● registrazione agli eventi del DOM: o è fondamentale utilizzare $scope.$apply per propagare le modifiche ● registrazione dei watch
    17. 17. AngularJS Advanced 17.07.2014 Direttive - transclude transclude: true, template: '<div><div …></div><div ng-transclude></div></div>' <div ng-controller="homeController"> <div cmsw-spinner="…" …> <button …>Carica</button> <span …></span> </div> </div> <div ng-controller="homeController"> <div cmsw-spinner="…" …> <div …> </div> <div> <button …>Carica</button> <span …></span> </div> </div> </div>
    18. 18. AngularJS Advanced 17.07.2014 Direttive - transcludeFn function([scope], cloneLinkingFn) ● scope - è opzionale, di default viene usato quello della direttiva ● cloneLinkingFn - è una callback a cui viene passato l’elemento clonato e collegato la quale serve per inserirlo nel DOM
    19. 19. AngularJS Advanced 17.07.2014 Direttive - compilazione compile: function(tElement, tAttrs) { ... } ● modifica il DOM del template ● non ha accesso allo scope ● è invocata per ogni direttiva ● *ritorna una funzione/oggetto di link ● migliora le performance
    20. 20. AngularJS Advanced 17.07.2014 Direttive - comunicazione ● Direttiva → Controller: o scope isolato con binding & ● Controller → Direttiva: o scope isolato con binding mono o bidirezionale ● Direttiva ←→ Direttiva: o attraverso i controller
    21. 21. AngularJS Advanced 17.07.2014 Direttive - Q&A Domande? (Sperando di sapervi rispondere :-D) 5 min
    22. 22. AngularJS Advanced 17.07.2014 Testing ● AngularJS ● Direttive ● Testing (Unit) ● Gestione delle dipendenze ● Mettiamo tutto insieme ● Q&A
    23. 23. AngularJS Advanced 17.07.2014 Testing - Jasmine ● Stile BDD ● Autonomo ● JavaScript puro ● Test runner: o una semplice pagina HTML; o Karma per Node.js; o Chutzpah per Visual Studio;
    24. 24. AngularJS Advanced 17.07.2014 Testing - Jasmine - anatomia describe('Test', function() { var testFixture; beforeEach(function() { … }); afterEach(function() { … }); it('should fail', function() { expect(true).toBe(false); }); });
    25. 25. AngularJS Advanced 17.07.2014 Testing - Jasmine - spies ● Mock (FakeItEasy, mockito, etc.) ● Comportamento: o invocazione metodo originale o invocazione metodo fake o lancio eccezioni ● Asserzioni sull’invocazione dei metodi: o argomenti o ordine
    26. 26. AngularJS Advanced 17.07.2014 Testing - angular.mock ● module(…) - registrare moduli per l’injector ● inject(…) - inietta le variabili richieste ● $httpBackend - simula la comunicazione HTTP con il back end e di definire delle attese: o when???(…).response(…) o expect???(…)[.response(…)] o flush([count])
    27. 27. AngularJS Advanced 17.07.2014 Testing - controller ● Caricare il modulo ● Farsi iniettare le dipendenze ● Creare uno scope ● Creare i mock necessari ● Creare il controller ● Utilizzare il metodo $apply dello scope
    28. 28. AngularJS Advanced 17.07.2014 Testing - direttive ● Caricare il modulo ● Preparare l’HTML di test (stringa) ● Farsi iniettare $compile e $rootScope ● Compilare l’HTML ● Modificare scope → verificare il DOM ● Modificare il DOM e lanciare gli eventi → verificare lo scope
    29. 29. AngularJS Advanced 17.07.2014 Gestione delle dipendenze ● AngularJS ● Direttive ● Testing (Unit) ● Gestione delle dipendenze ● Mettiamo tutto insieme ● Q&A
    30. 30. AngularJS Advanced 17.07.2014 Dipendenze - AngularJS’s way Modulo - raggruppamento di “oggetti Angular” angular.module('???', […]) .config(function(…){…}) .run(function(…){…}) var m = angular.module('???') Angular non si occupa di caricare gli script!
    31. 31. AngularJS Advanced 17.07.2014 Dipendenze - RequireJS ● Definisce le dipendenze fra file/moduli ● Carica file/moduli ● Garantisce l’ordine di caricamento ● Asincrono ● Usabile con librerie non-RequireJS ● Elimina variabili globali ● Include un tool per minimizzare e offuscare il codice (r.js)
    32. 32. AngularJS Advanced 17.07.2014 Dipendenze - RequireJS require.config({ baseUrl: '…', paths: { 'nome': 'path/fuori/da/baseUrl', … }, shim: { 'nome': { deps: […], exports: '…' }, … } }); require([…], function(){ }); //<script data-main="main.js" src="app/vendor/require.js"> main.js
    33. 33. AngularJS Advanced 17.07.2014 Dipendenze - RequireJS ● Definire nelle sezioni path e shim, la posizione e le dipendeze delle librerie angular ● Bootstrap manuale: o No ng-app o utilizzare plugin domReady o utilizzare angular.bootstrap(…) ● Definire due main.js per test ed “esecuzione”
    34. 34. AngularJS Advanced 17.07.2014 Ricordate!!!
    35. 35. AngularJS Advanced 17.07.2014 Riferimenti ● AngularJS - https://angularjs.org/ ● Jasmine - http://jasmine.github.io/2.0/introduction.html ● RequireJS - http://requirejs.org/ ● Build custom directives with AngularJS - http://www.ng- newsletter.com/posts/directives.html
    36. 36. AngularJS Advanced 17.07.2014 Q&A Domande? (Sperando di sapervi rispondere :-D) 15 min

    ×