Présentation AngularJS – Jean Detoeuf



Présentation AngularJS – Jean Detoeuf

0 0


talk-angularjs-introduction

Introduction talk about AngularJS in French

On Github thebignet / talk-angularjs-introduction

Présentation AngularJS

Jean Detoeuf

Sommaire

  • Introduction et besoin
  • Utilisation basique d'AngularJS
  • Tests unitaires
  • Composants d'AngularJS
  • Création de composants
Pourquoi un autre framework JS ? Comment utiliser AngularJS Comment bien l'utiliser avec les tests Composants inclus et en créer

Jean Detoeuf

  • Ingénieur concepteur/développeur
  • Passionné de Java, Spring, Web, Javascript
  • Adore plein de choses hype comme le growth hacking, nodeJS, la programmation reactive, fonctionnelle, le continuous delivery, sauter dans le vide et les choses qui vont vite
  • Aime la bière, les voyages, le roller, courir
  • Et les nouvelles technos en général

Sondage

Qui

  • A déjà utilisé JavaScript ?
  • A déjà utilisé jQuery ?
  • A déjà utilisé un autre framework JavaScript ?
  • A déjà entendu parler d'AngularJS ?
  • A déjà utilisé AngularJS ?
  • Est à l'aise avec AngularJS ?
Demander de lever la main. Si oui à la dernière, demander à partir !

Intro

N'hésitez pas à poser des questions

Besoin

  • Fonctionnement standard client/serveur avant 2005 : le serveur produit une page, le client en fait le rendu
  • 2005 : Arrivée d'AJAX
  • Des "bouts" de page peuvent être affichés à la demande : il n'est pas nécessaire de recharger une page à chaque action
  • Aucune intelligence réelle côté client
La génération de page est statique et c'est le serveur qui fait tout Arrivée d'ajax boulverse ce schéma On évite au moins de recharger toute la page. Gain en temps de chargement ressenti Bien mais on sent qu'on peut faire mieux

Evolution des interfaces web

J'ai présenté les deux premier modèles C'est le troisième modèle qui est utilisé aujourd'hui Le client a plus d'intelligence

Pourquoi on n'avait pas fait comme ça avant ?

  • JavaScript existe depuis longtemps
  • L'évolution de la puissance des terminaux (PC, mobile) permet de placer de l'intelligence côté client.
  • Les moteurs JavaScript se sont améliorés à partir de 2008 (merci AJAX).
  • Même les mobiles peuvent tirer parti de cette amélioration
  • Framework JS développé par Google
  • Première version 2009
  • Fondé sur la programmation déclarative
  • Architecture MVC ou plutôt MVVM
  • Injection de dépendance

Pourquoi apprendre un framework JavaScript ?

  • Vers un monde d'API
  • Applications riches
  • Applications pour mobiles et tablettes avec PhoneGap
  • Présenter des données d'une manière plus simple et efficace
  • Intelligence "rapide" côté serveur avec Node.js

Points forts

  • Open Source
  • Maintenu par Google
  • Injection de dépendance
  • Couplage faible entre présentation, données, composants métier
  • Tests unitaires et bout en bout
  • Compatible REST
  • Compatible WebSockets

Points faibles

  • Encore en évolution
  • Ne fonctionne pas sur IE6, et adaptations à faire pour IE7 et IE8
  • La gestion des fichiers peut vite devenir cahotique si on ne la maitrise pas.
  • Validation à implémenter côté client
  • Possibilité d'être remplacé un jour par DartJS
La gestion des fichiers est un pb qui concerne tous les FW JS récents

Concurrents

  • Backbone.js
  • Ember.js
  • Knockout.js
  • React.js
  • Plusieurs frameworks qui gèrent le rendu HTML, les feuilles de style, voir même le Back Office
  • JQuery n'est pas un concurrent, il est complémentaire
  • La force d'AngularJS est de ne pas tout faire, de se concentrer sur le MVVM

Pourquoi AngularJS plutôt qu'un autre framework JavaScript ?

(Moi j'adore le jQuery, ça marche très bien...)
Des frameworks JavaScript il en sort tous les jours Plutôt que de vous donner la preuve, c'est internet qui va le faire

Concurrents

Utilisation d'AngularJS

Bases

Maintenant que vous êtes convaincus, voici les bases

Installation

  • Aller sur angularjs.org
  • Télécharger la dernière version et l'inclure dans sa page web
  • Ou utiliser le CDN Google pour l'inclure dans sa page web
<html ng-app="myApp">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
</head>
<body>
</body>
</html>
Installation très simple

Evaluations

  • Une évaluation permet d'afficher une valeur
  • Exemple : {{1+1}} affiche 2
<html ng-app="myApp">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
  <script type="text/javascript">
  var myApp = angular.module('myApp', []);
  </script>
</head>
<body>
	Réponse : {{ 7 * 6 }}
</body>
</html>

Démonstration

Injection de dépendances 1/2

  • Permet l'inversion de contrôle
  • Fonctionne par module
  • Un module peut dépendre d'autres modules
  • Il est alors possible de faire appel aux méthodes de ces modules
  • Permet la séparation de considérations
  • Code testable unitairement (un module représente une fonctionnalité et les autres modules peuvent être mockés)

Injection de dépendances 2/2

  • L'injection se fait simplement en l'ajoutant à la liste des dépendances du module
  • Puis le module peut être utilisé en paramètre d'une fonction
angular.module('myApp', ['Clock','Bell']);
var ringMyBell = function($scope,Clock,Bell){...}

controleur

  • Conteneur permettant de gérer des variables
  • En JavaScript, des variables peuvent être des fonctions
  • Les variables d'un controleur sont contenue dans son $scope
  • Le $scope permet l'étanchéité des variables au sein du controleur
<html ng-app="myApp">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
  <script type="text/javascript">
  var myApp = angular.module('myApp', []);
  myApp.controller('MyCtrl', function MyCtrl($scope) {
    $scope.reponse = 42;
  });
  </script>
</head>
<body ng-controller="MyCtrl">
  Réponse : {{ reponse }}
</body>
</html>

Démonstration

Répéteur

  • ng-repeat permet d'itérer sur une liste (ie. foreach)
<html ng-app="myApp">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
  <script type="text/javascript">
  var myApp = angular.module('myApp', []);
  myApp.controller('MyCtrl', function MyCtrl($scope) {
    $scope.elems = [0,1,1,2,3,5,8,13];
  });
  </script>
</head>
<body ng-controller="MyCtrl">
  {{elems.length}} premiers éléments de la suite de Fibonacci :
  <ul><li ng-repeat="elem in elems track by $index">{{elem}}</li></ul>
</body>
</html>

Démonstration

Filtres 1/3

  • Permet de modifier le rendu d'une valeur
  • Peut s'appliquer sur des listes
  • Exemple de filtres :
    • filter
    • orderBy
    • limitTo
    • date
    • currency
    • json
    • lowercase
    • uppercase
    • number

Filtres 2/3

<html ng-app="myApp">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
  <script type="text/javascript">
  var myApp = angular.module('myApp', []);
  myApp.controller('MyCtrl', function MyCtrl($scope) {
    $scope.technos = ['JavaScript', 'HTML', 'CSS', 'Java'];
  });
  </script>
</head>
<body ng-controller="MyCtrl">
  Technologies :
  <ul><li ng-repeat="techno in technos">{{techno}}</li></ul>
  Technologies Java* :
  <ul><li ng-repeat="techno in technos | filter:'Java'">{{techno}}</li></ul>
</body>
</html>

Démonstration

Filtres 3/3

  • Possibilité de créer ses propres filtres
  • Permet de factoriser un comportement
<html ng-app="myApp">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
  <script type="text/javascript">
    var myApp = angular.module('myApp', []).filter('truncate', function () {
        return function (text,length) {
            return (text.length<=length)?text:(String(text).substring(0,length)+'...');
        };
    });
    myApp.controller('MyCtrl', function MyCtrl($scope) {
        $scope.blah = 'blah blah blah blah blah blah blah blah blah';
    });
  </script>
</head>
<body ng-controller="MyCtrl">
	<table>
		<tr><td>Avant filtre</td><td>{{blah}}<td/></tr>
		<tr><td>Après filtre de taille 18</td><td>{{blah|truncate:18}}<td/></tr>
	</table>
</body>
</html>

Démonstration

Binding bidirectionnel 1/3

  • Vue vers Modèle : Certains composants permettent de modifier le modèle à partir de la vue
  • Modèle vers Vue : Toute modification du modèle entraine la modification de la vue associée
  • AngularJS est assez intelligent pour savoir quels sont les composants affectés par une modification
  • Chaque mise à jour de la vue à partir du modèle s'appelle un digest
  • AngularJS optimise le digest pour le rendre très perfomant, voir instantané

Binding bidirectionnel 2/3

Binding bidirectionnel 3/3

<html ng-app="myApp">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
  <script type="text/javascript">
  var myApp = angular.module('myApp', []);
  myApp.controller('MyCtrl', function MyCtrl($scope) {
    $scope.nom = 'le monde';
  });
  </script>
</head>
<body ng-controller="MyCtrl">
  Bonjour <input ng-model="nom"/><br/>
  Comment ça va, {{nom}} ?
</body>
</html>

Démonstration

Ressources

  • Angular gère nativement le REST
  • Il est possible d'effectuer n'importe quelle requête HTTP
  • Définir une vraie ressource HTTP avec paramétrage de l'URI (ie. /user/:id ou /post/:name)
  • <html ng-app="myApp">
    <head>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
      <script type="text/javascript">
    var myApp = angular.module('myApp', ['ngResource']);
    myApp.factory('AngularJsIssues', function($resource){
      return $resource('https://api.github.com/repos/angular/angular.js/issues');
    });
    myApp.controller('MyCtrl', function MyCtrl($scope,AngularJsIssues) {
      $scope.issues = AngularJsIssues.query();
    });
      </script>
    </head>
    <body ng-controller="MyCtrl">
      <table>
        <tr>
          <th>Id</th>
          <th>State</th>
          <th>Title</th>
        </tr>
        <tr ng-repeat="issue in issues">
          <td ng-bind="issue.id"></td>
          <td ng-bind="issue.state"></td>
          <td ng-bind="issue.title"></td>
        </tr>
      </table>
    </body>
    </html>

Démonstration

Utilisation d'AngularJS

Tests

Introduction

  • Quoi ? des tests automatisés en JavaScript ??
  • Tests unitaires et tests bout en bout (E2E)
  • Lancement des tests avec
  • Les tests peuvent être lancés sur plusieurs navigateurs
  • Karma peut aussi faire les tests sur un port (ie. mobile ouvert sur un port d'écoute)

Exemple

  • Unit tests : Test d'un module
  • End-to-end tests : Test de plusieurs modules
  • Les interfaces peuvent être bouchonnées (voir angular.mock.inject)
  • Tous les exemples de cette présentation ont leur test
'use strict';
describe('myApp', function(){
  var curModule;
  beforeEach(curModule = module('myApp'));
  describe('myApp module', function(){
    it('should have a module', function() {
      expect(curModule).not.toBeNull();
    });
  });
  describe('Controller', function(){
    var scope, ctrl;
    beforeEach(inject(function($rootScope, $controller) {
      scope = $rootScope.$new();
      ctrl = $controller('MyCtrl', {$scope: scope});
    }));
    it('should have a controller', function() {
      expect(ctrl).not.toBeNull();
    });
  });
});

Utilisation d'AngularJS

Fonctions avancées

Directives 1/2

  • Utiliser des nouveaux tags
  • Utiliser des nouveaux attributs
<alert>Alerte !</alert>
<datepicker min="minDate" show-weeks="showWeeks"/>
		

Directives 2/2

  • Possibilité de créer ses directives
  • Comme si on réécrivait du HTML
  • Peut être "compilé"
<twitter-tweet-page/>
<google-plus-page/>
<facebook-like-page/>
<twitter-direct-message user="@thebignet"/>
<twitter-followers user="@thebignet"/>
<github-last-commit user="thebignet" project="pres-angularjs"/>
		

router

  • Permet de lier à une URI une vue et un controleur
  • /users affiche la vue imbriquée users.html avec le controleur UserCtrl

ui-router

  • Meilleur que le routeur intégré à AngularJS
  • Permet de gérer des états plutôt que des URI
  • Plusieurs vues/controleurs pour un URI
  • Vues imbriquées
  • Directive pour une navigation plus simple

Vues

  • Avec le routeur intégré à AngularJS
myApp.config(['$routeProvider',
function($routeProvider) {
  $routeProvider
    .when('/users', { templateUrl: 'users.html', controller: 'UserCtrl' })
    .otherwise({ redirectTo: '/' });
}]);
<div ng-view></div>

Vues

  • Avec ui-router
myApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider.state('users', { url: "/users", templateUrl: "users.html" })
});
<div ui-view></div>

Animations

  • Basé sur des évènements liés à des directives
  • Suite à l'ajout/suppression d'un élément à une liste
  • Suite à la modification d'une valeur
  • AngularJS applique des classes CSS spécifique avant et pendant l'action
  • Toutes les transitions CSS3 sont utilisables

jQuery

  • Version allégée de jQuery inclue dans AngularJS
  • Peut être surchargée par la version complète
  • La version allégée ne contient pas les sélecteur css et c'est pour votre bien car ce n'est pas la philosophie d'AngularJS

Bons amis d'AngularJS

Intégration continue

  • Les tests peuvent être exécutés sur plusieurs navigateurs à chaque sauvegarde en local ou à chaque commit
  • Karma peut être lancé par Jenkins, Sonar, ou Travis
  • Les rapports produits sont au format Junit

Pour monter un projet rapidement

  • Angular-seed
  • Framework CSS : Twitter Bootstrap, Foundation
  • Utiliser Yeoman avec generator-angular ou generator-jhipster

Hébergement

  • Le serveur peut héberger les ressources front et fournir l'API
  • Possibilité d'avoir un serveur statique pour le front et une API pour le back
  • Plus de flexibilité quant à la charge reposant sur chacun
  • Les serveurs frontaux peuvent mettre les ressources en cache efficacement
  • Les serveurs d'API peuvent être dimensionnés
  • Ce découpage se prête plus facilement à un cloud

Questions ?

Remerciements

Merci !

0