Intro à angular

559 views

Published on

http://pierrci.github.io/intro-angular/

Une présentation d'Angular destinée à un public débutant en javascript et se concentrant sur l'aspect "pratique", servant de fil rouge dans le cadre d'une formation de stage. Elle n'a absolument pas la prétention d'être exhaustive.

Published in: Software

Intro à angular

  1. 1. Welcome ! I have nothing to o튵䎣er but blood, toil, tears, and sweat. W. Churchill, 13 mai 1940 @pierrci
  2. 2. Evolution of Web Apps https://evolution-of-apps.剭녲rebaseapp.com David East - Firebase & Angular team
  3. 3. So... Angular !
  4. 4. En 4 mots clés Framework Javascript SPA (o_O) Google MVW Au sujet de MVC / MVVM : http://www.docdoku.com/blog/2015/02/17/architecturer-ses-applications-js-pattern-mvvm/ http://stackover�ow.com/questions/667781/what-is-the-di튵䎣erence-between-mvc-and-mvvm/
  5. 5. Aujourd'hui, version 1.X - https://angularjs.org/ Demain, version 2.X - https://angular.io/ - AngularJS however is not an example of developers maintaining backwards compatibility. It takes pleasure in starting over. In fact, you can just about rip up your old Angular apps now. It’s for your own good. @EdwardCGordon packtpub.com La classe non ?
  6. 6. Ready for roller coasters ?
  7. 7. Sans Angular... <html>      <head>         <title>Index</title>      </head>      <body>         Name: <input type="text" id="myInputBox">          Hello <span id="nameSpan"></span> !                      <script> </script>      </body>  </html>               var inputElem = document.getElementById("myInputBox");              inputElem.addEventListener('keyup', function() {                  var text = inputElem.value;                  document.getElementById("nameSpan").innerHTML = text;              });           Avec Angular ! <html>      <head>         <title>Index</title>          <script src="../angular.min.js"></script>      </head>      <body ng­app>          Name: <input type="text" ng­model="nameModel">          Hello {{ nameModel }} !      </body>  </html>
  8. 8. <html>      <head>          <title>Index</title>          <script src="../angular.min.js"></script>      </head>      <body ng­app>          Name: <input type="text" ng­model="nameModel">          Hello {{ nameModel }} !      </body>  </html> ng-app : directive de bootstrap ("démarrage"), indique à angular où se situe l'application dans la page HTML. ng-model : directive qui associe ("bind") la valeur d'un champ à une variable. {{ nameModel }} : expression angular, elle est évaluée par angular et son résultat est inséré dans la page.
  9. 9. <demo />
  10. 10. Les modules <body ng­app="monApplicationAngular"> La valeur passée à ngApp est le nom du module principal de l'application. Un module contient les composants de notre application : controllers, directives, services, 剭녲ltres...
  11. 11. Pour pouvoir ajouter ces composants, il faut déclarer le module côté javascript : var app = angular.module("monApplicationAngular", [      "ngRoute",      "ngResource",      //...  ]);  // Dans sa forme la plus simple :  // var app = angular.module("monApplicationAngular", []); Une fois déclaré, on peut l'appeler et lier des composants : angular      .module("monApplicationAngular")      .directive("uneDirective", maDirective);        function maDirective() {      //...  }
  12. 12. Les expressions Angular <body ng­app="monApplicationAngular">      1 + 2 = {{ 1 + 2 }}      Nom de l'utilisateur : {{ user.name }}      Loisir n° 3 de l'utilisateur : {{ user.loisirs[2] }}  </body> Comment et où déclarer user ? => Dans un controller
  13. 13. Les controllers C'est là que l'on interagit avec les données de la vue angular      .module("monApplicationAngular")      .controller("HomeController", HomeController);  function HomeController() {      var vm = this; // vm pour ViewModel      vm.user = {          name: "Pierric",          loisirs: ['ski', 'lecture', 'musique']      }  } On "bind" les méthodes et variables qui nous intéressent au this de HomeController
  14. 14. Il faut penser à déclarer le controller dans le HTML grâce à la directive ngController <body ng­app="monApplicationAngular">      <div ng­controller="HomeController as home">          Nom de l'utilisateur : {{ home.user.name }}          Loisir n° 3 de l'utilisateur : {{ home.user.loisirs[2] }}      </div>  </body> On utilise la syntaxe controllerAs, indissociable du binding à l'instance du controller (le this côté JS), en spéci剭녲ant un alias pour notre controller : home (arbitraire) -Do You Like Your Angular Controllers with or without Sugar? @John_Papa
  15. 15. $scope Dans le javascript, on aurait pu aussi lier le modèle à $scope au lieu de this, sans utiliser la syntaxe controllerAs : function HomeController($scope) {      $scope.user = {          name: "Pierric",          loisirs: ['ski', 'lecture', 'musique']      }  } Côté HTML : <div ng­controller="HomeController">      Nom de l'utilisateur : {{ user.name }}      Loisir n° 3 de l'utilisateur : {{ user.loisirs[2] }}  </div>
  16. 16. Les limites de $scope <div ng­controller="MainCtrl">     {{ title }}      <div ng­controller="AnotherCtrl">          {{ title }}          <div ng­controller="YetAnotherCtrl">              {{ title }}          </div>      </div>  </div> On préfèrera limiter $scope à l'utilisation de méthodes qui en dépendent telles que $watch, $on ou $broadcast - function HomeController($scope) {      var vm = this;      vm.username = "Pierric";      $scope.$on('someEventFiredFromElsewhere', function (event, data) {          // do something!      });  } Digging into Angular’s “Controller as” syntax @toddmotto
  17. 17. <demo />
  18. 18. Les directives ngApp, ngController, ngModel, ... sont des directives Ce sont des marqueurs positionnés sur des éléments du DOM qui indiquent à angular quel comportement attacher à un élément et/ou quelle transformation y apporter De nombreuses directives sont intégrées nativement : https://code.angularjs.org/1.4.11/docs/api/ng/directive
  19. 19. Directives de template : insère ou pas un élément dans le DOM en fonction de la valeur de l'attribut ngIf <div ng­if="isVisible">I'm gonna disappear</div> : permet de parcourir les éléments d'un tableau et d'a皉푰cher leur valeur ngRepeat <div ng­repeat="user in users">{{ user.name }}</div> : modi剭녲e le contenu d'un élément suivant la valeur d'une expression ngSwitch <div ng­switch="isEditable">      <div ng­switch­when="false">Name : {{ user.name }}</div>      <div ng­switch­when="true"><input type="text" ng­model="user.name"></div>  </div>
  20. 20. Directives de style / : modi剭녲e la visibilité d'un élément du DOM suivant la valeur de l'expression en paramètre ngShow ngHide <div ng­hide="hidden">Hello hide</div>  <div ng­show="hidden">Hello show</div> : conditionne dynamiquement les classes d'un élément du DOM suivant la valeur d'expressions ngClass <p ng­class="{bold: important, red: error}">Map Syntax Example</p> : modi剭녲e la valeur de l'attribut disabled suivant l'expression spéci剭녲ée ngDisabled <button ng­disabled="isDisabled">Disabled</button>
  21. 21. Directives d'action : permet d'appeler une fonction ou d'évaluer une expression lors d'un clic sur l'élément ngClick <div ng­click="click()">Click me!</div>  <button ng­click="count = count + 1" ng­init="count = 0">Increment</button> / : associe des actions à des événements claviers ngKeydown ngKeyup <input type="text" ng­keydown="down()" ng­keyup="up()"> : spéci剭녲e l'action à e튵䎣ectuer pour l'envoi d'un formulaire. Ne pas combiner avec ngClick ! ngSubmit <form ng­submit="submit()" ng­controller="SimpleFormController">      <input type="text" ng­model="text" name="text">      <input type="submit" id="submit" value="Submit">  </form>
  22. 22. <demo />
  23. 23. Les Filtres Les 剭녲ltres permettent de formatter et de... 剭녲ltrer (!) les expressions auxquelles ils sont appliqués : {{ expression | filter }}  {{ expression | filter1 | filter2 }} <!­­ Ils peuvent être combinés ­­> {{ expression | filter:arg1:arg2 }} <!­­ On peut passer des arguments ­­> Exemples : {{ 'Mon texte' | uppercase }}  {{ '25.465' | number:2 | currency:'$'}} <!­­ seulement 2 décimales ­­> Liste des 剭녲ltres natifs : https://docs.angularjs.org/api/ng/剭녲lter
  24. 24. Soit le tableau suivant dans un controller: var jb = {name: 'JB', gender: 'male'},      cyril = {name: 'Cyril', gender: 'male', birth: '1990­11­25'},      agnes = {name: 'Agnes', gender: 'female', birth: '1991­07­22'},      cedric = {name: 'Cedric', gender: 'male', birth: '1992­02­22'};  vm.ninjas = [jb, cyril, agnes, cedric]; Avec le HTML suivant : <p>{{ ninjas | orderBy:'name' | limitTo:2 }}</p>  <div ng­repeat="ninja in ninjas">      {{ ninja.birth | date:'yyyy' }}  </div> On obtiendra : [      {"name":"Agnes","gender":"female","birth":"1990­07­22"},      {"name":"Cedric","gender":"male","birth":"1990­02­22"}  ]  1990  1991  1992
  25. 25. Le filtre Filter 剭녲lter permet d'appliquer un 剭녲ltre personnalisé aux éléments d'un tableau <input type="text" ng­model="searchText">  <table id="searchTextResults">      <tbody><tr><th>Name</th><th>Birth date</th></tr>      <tr ng­repeat="ninja in ninjas | filter:searchText">          <td>{{ friend.name }}</td>          <td>{{ friend.birth | date:'dd/MM/yyyy' }}</td>      </tr>  </tbody></table> <label>Any: <input ng­model="search.$"></label><br>  <label>Name only <input ng­model="search.name"></label><br>  <label>Gender only <input ng­model="search.gender"></label><br>  <label>Equality <input type="checkbox" ng­model="strict"></label><br>  <table id="searchObjResults">      <tbody><tr><th>Name</th><th>Gender</th></tr>      <tr ng­repeat="ninja in ninjas | filter:search:strict">          <td>{{ ninja.name }}</td>          <td>{{ ninja.gender }}</td>      </tr>  </tbody></table>
  26. 26. <demo />
  27. 27. Time for practice ! - Unit 1Learn AngularJS | Codecademy - Levels 1 / 2 / 3Shaping up with AngularJS | CodeSchool
  28. 28. Créer ses directives L'avenir du web est aux : découpage des fonctionnalités en modules réutilisables indépendamment. Web Components Les directives sont un avant-goût et permettent d'implémenter une partie de cette logique. peut devenir : <div>      <h1 class="title">{{ book.title }}</h1>      <h2 class="author">{{ book.author }}</h2>      <div class="extract">{{ book.extract }}</div>  </div> <book­details data­book="main.book"></book­details>
  29. 29. Fichier bookDetails.directive.js : angular.module('myApp')         .directive('bookDetails', bookDetails);  // camelCase côté JS !           function bookDetails() {      return {            // Une directive retourne un objet de "configuration"          restrict: 'E',  // La directive doit être appelée sous forme d'élément          scope: {        // On crée un nouveau scope isolé propre à la directive              book: '='   // On récupère l'objet passé à l'attribut correspondant          },          templateUrl: 'bookDetails.tpl.html',  // Indique où aller chercher le HTML      };  } Fichier bookDetails.tpl.html : <div>      <h1 class="title">{{ book.title }}</h1>      <h2 class="author">{{ book.author }}</h2>      <div class="extract">{{ book.extract }}</div>  </div>
  30. 30. restrict : indique comment doit être appelée la directive dans le HTML - A pour attribut, E pour élement et C pour classe CSS. On peut les combiner, par exemple 'AEC'. scope : crée un scope isolé pour la directive. On récupère les éléments du scope englobant via les attributs. '@' pour passer une valeur (chaîne de caractères), '=' pour du two-way binding sur un objet.
  31. 31. controller : une directive peut avoir son propre controller. controllerAs : permet de spéci剭녲er un alias pour le controller, comme avec ng-controller = ... as ... bindToController : indissociable de ControllerAs, lie les propriétés à l'instance du controller plutôt qu'au scope. ...  controller: function () {      var vm = this;          vm.selectBook = function () { ... }  },  controllerAs: 'bookDetails',  bindToController: true  ... https://docs.angularjs.org/api/ng/service/$compile
  32. 32. <demo />
  33. 33. Time for practice ! - Unit 2Learn AngularJS | Codecademy - Level 4Shaping up with AngularJS | CodeSchool
  34. 34. Les services Les services sont des objets dans lesquels on met le code correspondant à la logique métier de l'application. Ils sont aussi utilisés pour organiser le code partagé de l'application. Les services sont : Lazy : paresseux, ils ne sont instanciés que lorsque l'application en a besoin Singletons : ils seront instanciés une seule fois et cette instance est ensuite utilisée partout
  35. 35. Les services natifs : permet de faire simplement des requêtes AJAX. Renvoie une promise avec une callback de succès et une autre d'échec. $http $http({method: 'GET', url: '/serverUrl'})      .success(function(data, status, headers, config){ ... })      .error(function(data, status, headers, config){ ... }); : service plus haut niveau, utilisé pour interagir avec des . Nécessite le module ngResource. $resource API REST { 'get':    {method:'GET'},    'save':   {method:'POST'},    'query':  {method:'GET', isArray:true},    'remove': {method:'DELETE'}, 'delete': {method:'DELETE'} }; var Poneys = $resource('/races/:raceId/poneys/:poneyId',       { raceId: 24, poneyId: '@id'}, { run: { method: 'PUT' }});  var fury = Poneys.save({ name: 'Fury Red'});
  36. 36. : rend accessible l'URL de la page actuelle à notre application et expose plusieurs méthodes. $location // avec l'url http://example.com/#/some/path?foo=bar&baz=xoxo  var path = $location.path(); // => "/some/path"  var searchObject = $location.search(); // => {foo: 'bar', baz: 'xoxo'} / : permettent de wrapper setTimeout et setInterval dans le cycle de vie de l'application angular. $timeout $interval var delayedFn = $timeout(function(){ ... }, 1000) // Après 1 seconde.  var recurringFn = $interval(function(){ ... }, 1000, 0) // Chaque seconde. Autres wrappers ($window, $document...) et services natifs : https://docs.angularjs.org/api/ng/service
  37. 37. Les Promises Nouveauté de l'EcmaScript 6, implémentée via le service $q. Utilisée lors de traitements asynchrones tels que les requêtes AJAX avec $http. Une promise peut avoir deux résultats : succès ou échec. $http.get(...)      .then(function(data){          // succès, promise résolue      }, function(error){          // erreur, promise rejetée  });
  38. 38. $q function asyncGreet(name) {      var deferred = $q.defer(); // On crée un objet deferred      $timeout(function() { // Ici on crée artificiellement un délai          deferred.notify('About to greet ' + name + '.');                if (okToGreet(name)) {              deferred.resolve('Hello, ' + name + '!'); // succès          } else {              deferred.reject('Greeting ' + name + ' is not allowed.'); // échec          }      }, 1000);            return deferred.promise; // On retourne la promise de deferred  }  var promise = asyncGreet('Robin Hood'); // La fonction retourne une promise  promise.then(function(greeting) {      alert('Success: ' + greeting); // En cas de succès  }, function(reason) {      alert('Failed: ' + reason); // En cas d'échec  }, function(update) {      alert('Got notification: ' + update); // Indication de progression  });
  39. 39. <demo />
  40. 40. L'injection de dépendance (DI) Pour pouvoir utiliser un composant dans un autre, angular utilise un système d'injection de dépendance. function HomeController($scope, $http) { ... }  // function HomeController($http, $scope) { ... } // équivalent ! HomeController.toString(); // "function HomeController($scope, $http) { ... }" Pour éviter les problèmes en cas de mini剭녲cation du javascript, on "annote" les composants : HomeController.$inject = ['$scope', '$http'];  function HomeController($scope, $http) { ... } // Il vaut mieux garder le même ordre...
  41. 41. Time for practice ! - Unit 3Learn AngularJS | Codecademy - Level 5Shaping up with AngularJS | CodeSchool
  42. 42. ngRoute ngRoute est le module angular de base chargé du routage. Il est composé d'une directive ngView, d'un $routeProvider et de 2 services : $route et $routeParams. ngView indique quelle partie de la SPA sera mise à jour : <div ng­view=""></div>
  43. 43. $routeProvider $routeProvider permet de déterminer les routes de l'application et de faire le lien entre URL, template et controller. angular      .module("monApplicationAngular")      .config(configure);        function configure($routeProvider) {      $routeProvider          .when('/races/:raceId?', { // raceId est un paramètre facultatif              templateUrl: 'races.html',              controller: 'RacesController' // Remplace ng­controller="..."          })          .when('/', {              templateUrl: 'poneys.html',              controller: 'PoneysController'              controllerAs: 'poneys' // Remplace ng­controller="... as ..."          })          .otherwise('/'); // Si l'url ne correspond pas, redirection  }
  44. 44. $routeParams Service permettant de déterminer les paramètres de la route. Combinaison de $location.search() et $location.path(). // Avec une url = http://www.example.com/#/races/13?poney=10  $routeParams ==> { raceId: "13", poney: "10" }
  45. 45. Time for practice ! - Units 4 / 5Learn AngularJS | Codecademy
  46. 46. Ressources utiles - ebook - [fr] chez video2brain - [fr] par - [fr] par - [fr] sur MDN - [fr] Le guide du développeur Devenez un ninja avec AngularJS 2 formations vidéos Formation vidéo AngularJS @gra剭녲kart_fr Le guide de style Angular @john_papa Une réintroduction à Javascript

×