Mickael Jeanroy



Mickael Jeanroy

1 0


insa-angular


On Github mjeanroy / insa-angular

Mickael Jeanroy

mickael.jeanroy@zenika.com
INSA LYON - IF 2014
19 / 11 / 2014

Who am I ?

Programme

Javascript Ecosystème & Best practice Angular.js TP Build your own Angular.js
Du code, beaucoup de code !

Javascript

Introduction
  • Créé en 1995 par Brendan Eich pour Netscape
  • Standardisé: ECMAScript
    • ECMAScript 3 : 1999
    • ECMAScript 5 : 2009
    • ECMAScript 6 : encore en cours de développement !
  • ECMAScript 5 est la version actuellement implémentée dans les navigateurs (Chrome, Firefox, Safari, IE10)
  • Souvent considéré comme un langage "sale", pas maintenable etc.
  • On va voir aujourd'hui qu'en connaissant ses faiblesses, il devient au contraire un langage très puissant.

Javascript

Introduction

Javascript

Introduction
  • Langage de script
  • S'exécute dans une VM (Virtual Machine)
    • Browser: V8 (Chrome) ; SpiderMonkey (Firefox) ; JavaScriptCore (Safari) etc.
    • Serveur: V8 (NodeJS) ; Rhino (Java) etc.
  • La mémoire est gérée grâce à un garbage collector
  • Langage dynamique
  • Langage faiblement typé
  • Langage orienté prototype

Javascript

Debug
  • Le plus basique: console.log
  • Permet de laisser des traces sur les appels
  • Attention: certaines vieilles versions d'IE ne le supportent pas
  • Chrome ajoute certaines features: console.table() / console.time() / console.memory etc.
// Fonction nommée "foo"
function foo() {
  console.log('hello world', 'hello bar');
}
					

Javascript

Debug
  • Chrome Dev Tools : le meilleur !
  • Firebug
  • Safari Web Inspector
  • Opera DragonFlyx
  • IE : présent depuis IE9

Javascript

Introduction

Javascript

Introduction

Javascript

Introduction

Javascript

Un langage faiblement typé
  • Le mot clé "var" permet de déclarer une variable
  • Peu de type: number, string, boolean, function, null
  • Une variable sans aucune valeur est "undefined"
  • Les objets et les tableaux permettent de les composer
  • Une variable n'a pas de type fixe (typage dynamique)
var foo;
console.log(foo); // 'undefined'
console.log(typeof foo); // 'undefined'

foo = 5;
console.log(typeof foo); // 'number'

foo = 'string';
console.log(typeof foo); // 'string'

foo = true;
console.log(typeof foo); // 'boolean'
					

Javascript

Les tableaux
  • Une seule structure de données: les tableaux
  • Suite ordonnée d'éléments, chaque élément étant accessible par son index
  • La propriété "length" donne la taille du tableau
  • ECMAScript 6 apporte de nouvelles structures de données: Set, WeakSet, Map, WeakMap
var foo = [1, 2, 3];
console.log(foo); // [1, 2, 3]

foo.push('string', true);
console.log(foo); // [1, 2, 3, 'string', true]

console.log(foo.length); // 5
console.log(foo[4]); // true
console.log(foo[5]); // undefined
					

Javascript

Les objets
  • En javascript, un objet est dynamique: on peut lui rajouter un attribut au runtime
  • Ni plus, ni moins qu'une map clé valeur
var foo = {};
console.log(typeof foo); // 'object'
console.log(foo); // {}

foo = {
  id: 1
};
console.log(foo); // {id: 1}

foo.name = 'Mickael';
console.log(foo); // {id: 1, name: 'Mickael'}

foo.skills = ['Js', 'Java'];
console.log(foo.skills); // ['Js', 'Java']
console.log(foo['skills']); // ['Js', 'Java']
					

Javascript

Les objets
  • Il est possible d'itérer simplement sur tous les attributs d'un objet
var foo = {
  id: 1,
  name: 'foo'
};

for (var key in foo) {
  console.log(key + ' = ' + foo[key]);
}

// id = 1
// name = foo
					

Javascript

Spécificités
  • En javascript, on distingue égalité et égalité stricte
    • L'opérateur "==" (négation: "!=") permet de comparer deux objets indépendamment du type
    • L'opérateur "===" (négation: "!==") permet de comparer deux objets en prenant en compte les types
  • Pour le cas des objets et des tableaux, c'est toujours une comparaison d'instance qui est faite!
var foo = 1;
var bar = '1';
console.log(foo == bar);  // true
console.log(foo === bar); // false

console.log([1, 2, 3] == [1, 2, 3]);  // false
console.log([1, 2, 3] === [1, 2, 3]); // false
					

Javascript

Spécificités
  • Question: qu'affiche ce code ?
console.log('' == '0'); // ???
console.log('' == 0);   // ???
console.log('0' == 0);  // ???
					

Javascript

Spécificités
WTF ??
console.log('' == '0'); // false
console.log('' == 0);   // true
console.log('0' == 0);  // true
					

Javascript

Spécificités
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.1

Javascript

Spécificités
  • Pour simplifier: Javascript essaye de rapprocher les variables vers deux types identiques.
  • Cela peut amener à quelques spécificités un peu "étranges".
  • Simplifiez-vous la vie, utilisez toujours l'égalité stricte !

Javascript

Un langage orienté fonctionnel
  • En javascript, les fonctions sont partout
  • Considéré comme un type comme un autre: le type "function" est un type comme un autre
  • Une fonction peut être nommée ou anonyme
// Fonction nommée "foo"
function foo() {
  console.log('hello world');
}

foo();

// Fonction anonyme qu'on affecte à une variable "foo"
var foo = function () {
  console.log('hello world');
};

foo();
					

Javascript

Un langage orienté fonctionnel
  • Une fonction a un nombre de paramètre variable
  • Le mot clé "arguments" au sein d'une fonction permet de récupérer la liste des paramètres
  • Une fonction peut ne rien retourner
// Fonction nommée "foo"
function foo(param1, param2) {
  console.log(param1, param2, 'arguments = ', arguments);

  if (param1 === 1) {
    return true;
  }
}

foo();         // undefined, undefinfed, arguments = []
foo(1);        // 1, undefinfed, arguments = [1]
foo(1, 2);     // 1, 2, arguments = [1, 2]
foo(1, 2, 3);  // 1, 2, arguments = [1, 2, 3]
					

Javascript

Un langage orienté fonctionnel
  • Une fonction peut être donnée en paramètre à une autre fonction
  • Une fonction peut retourner une autre fonction
  • En langage fonctionnel, de telles fonctions sont appelées fonctions d'ordre supérieur
  • Une fonction peut également être affectée à un attribut d'un objet
  • Avec Angular.js, on manipule et on écrit des fonctions tout le temps

Javascript

Un langage orienté fonctionnel
// Fonction nommée "foo": cette fonction prend en paramètre une fonction
// à exécuter
function foo(func) {
  func();
}

// Ce code donne une fonction anonyme en paramètre de la fonction "foo"
foo(function () {
  console.log('hello world');
});

// Ce code déclare une fonction nommée "myFunc"
// Cette fonction est ensuite donnée en paramètre de la fonction "foo"
function myFunc() {
  console.log('hello world');
}

foo(myFunc);
					

Javascript

Un langage orienté fonctionnel
// Fonction nommée "foo"
// Cette fonction renvoie une fonction permettant de "logguer" le
// contenu d'un tableau lorsqu'elle est exécutée
function foo(array) {
  return function () {
    for (var i = 0; i < array.length; i++) {
      console.log(array[i]);
    }
  };
}

var displayArray1 = foo([1, 2, 3]);
var displayArray2 = foo(['foo', 'bar']);

displayArray1(); // 1, 2, 3
displayArray2(); // 'foo', 'bar'
					

Javascript

Un langage orienté fonctionnel
// On déclare un objet avec une fonction comme attribut
var batman = {
  name: 'Batman',
  speak: function () {
    console.log('I am Batman');
  }
};

console.log(batman); // {name: "Batman", speak: function} 
console.log(typeof batman.speak); // 'function'

// Exécution de la fonction
batman.speak(); // 'I am Batman'
					

Javascript

Un langage orienté fonctionnel
Comme beaucoup de langages fonctionnels, ECMAScript 5 rajoute des fonctions de manipulation de listes: forEach, map, some, every, reduce etc.
// Exécute une fonction sur chaque élément d'un tableau
[1, 2, 3].forEach(function (current, idx) {
  console.log(current, idx);
});

// Applique une transformation à chaque élément et retourne
// un nouveau tableau contenant tous les résultas
// Ex: Multiplication par deux de tous les éléments
var newArray = [1, 2, 3].map(function (current) {
  return current * 2;
});

console.log(newArray); // 2, 4, 6
					

Javascript

Un langage orienté fonctionnel
// Vérifie une condition sur chaque élément d'un tableau
// Est-ce que tous les éléments sont pairs ?
[2, 4, 6].every(function (current) {
  return current % 2 === 0;
});

// Vérifie qu'une condition est vérifié sur au moins un élément d'un tableau
// Est-ce qu'au moins un élément est pair ?
[1, 2, 3].some(function (current) {
  return current % 2 === 0;
});

// Réduit le contenu du tableau à une valeur
// Ex: somme de tous les éléments du tableau
var reduceValue = [1, 2, 3].reduce(function (memo, current) {
  return memo += current;
}, 0);

console.log(reduceValue); // 6
					

Javascript

Un langage orienté prototype
  • Le langage Javascript n'est pas un langage orienté objet
  • Mais, cela ne signifie pas qu'on ne peut utiliser des objets !
  • On peut déclarer des constructeurs, la forme la plus classique est d'instantier une fonction avec le mot clé "new"
// Fonction nommée "foo"
var Hero = function (name) {
  this.name = name;
  this.speak = function () {
    console.log('I am ' + this.name);
  };
};

var batman = new Hero('Batman');
var superman = new Hero('Superman');

batman.speak();   // I am Batman
superman.speak(); // I am Superman
console.log(batman.speak === superman.speak); // false
					

Javascript

Un langage orienté prototype
  • Chaque objet dispose d'un "prototype"
  • Un prototype n'est rien de plus qu'une liste de propriétés (a.k.a un objet) partagé par toutes les instances d'un même type
var Hero = function (name) {
  this.name = name;
};

Hero.prototype = {
  speak: function () {
    console.log('I am ' + this.name);
  }
};

var batman = new Hero('Batman');     // I am Batman
var superman = new Hero('Superman'); // I am Superman
console.log(batman.speak === superman.speak); // true
					

Javascript

Un langage orienté prototype
  • ECMAScript 5 introduit la fonction Object.create pour créer un objet en lui donnant son "prototype"
var prototype = {
  speak: function () {
    console.log('I am ' + this.name);
  }
};

var batman = Object.create(prototype);
batman.name = 'Batman';

var superman = Object.create(prototype);
superman.name = 'Superman';
					

Javascript

Un langage orienté prototype
  • Le langage Javascript ne possède pas de "classe" au sens orienté objet.
    • Pas d'héritage
    • Pas de visibilité "private" ou "protected"
  • ECMAScript 6 introduit la notion de classes, mais reste limité à ce qu'on vient de voir (pas de visibilité, etc.)

Ecosystème

Frameworks

Ecosystème

Bonnes pratiques
  • Pendant longtemps, le Javascript est resté très "artisanal"
    • Pas de tests automatisés
    • Pas d'outils pour récupérer automatiquement ses librairies
  • Depuis quelques années, la communauté a développé tous les outils nécessaires !
  • Ces outils sont basés sur node.js

Ecosystème

Single Page Application
Wikipédia: Une application web monopage (en anglais single-page application ou SPA) est une application web accessible via une page web unique. Le but est d'éviter le chargement d'une nouvelle page à chaque action demandée, et de fluidifier ainsi l'expérience utilisateur.

Ecosystème

Single Page Application
  • Dans une Single Page Application (SPA), la page html n'est jamais rechargée entièrement
  • Seul une partie de la page, le contenu dynamique, est mis à jour
  • Exemples
    • Gmail
    • Facebook
    • etc.

Ecosystème

Single Page Application

Ecosystème

Single Page Application
Problème: la gestion de l'historique !

Ecosystème

Single Page Application
  • Solutions:
    • Pendant longtemps, la solution a été d'utiliser le contenu situé aptès le caractère # (hash) : c'est la solution utilisée par Gmail
    • HTML5 standardise ce concept avec l'API push state : c'est la solution utilisée par Facebook
    • L'API push state est à préférer car c'est un standard et facilite l'indexation par les moteurs de recherches

Ecosystème

REST
  • REpresentational State Transfer
  • Standard d'échange entre un client et un serveur
  • Style d'architecture
  • Indépendant du protocole (http, etc.)
  • Très rare de l'utiliser sur un autre protocole que http

Ecosystème

REST
Doit respecter ces contraintes:
  • Client / Serveur
  • Stateless
  • Les échanges peuvent être mis en cache
  • Identification de resources

Ecosystème

REST
Exemple: HTTP
  • Client / Serveur : OK par définition
  • Stateless : OK par définition, même si ça peut être compliqué à cause des sessions
  • Les échanges peuvent être mis en cach : OK via les headers HTTP
  • Identification de resources : OK via les URL

Ecosystème

REST
Exemple: Api Tweeter
  • GET /tweets
  • POST /tweets
  • PUT /tweets
  • DELETE /tweets

Ecosystème

Bonnes pratiques
  • Avant de livrer une application en production, il faut la "builder"
    • Concaténer ses fichiers javascript en un seul fichier
    • Minifier son code Javascript
    • Gzipper ses fichiers
    • Jouer les tests unitaires pour s'assurer de la stabilité du code
  • Le but est de garantir la non régression, de réduire le poids de la page, et donc améliorer l'expérience utilisateur !
  • Necessité d'automatiser ces tâches

Ecosystème

Build

Ecosystème

Test unitaires

Angular.js

by Google
  • Angular.js est un framework javascript "full stack"
  • Développé par Google (Miško Hevery, Igor Minar, Vojta Jina, etc.)
  • Version 1.3.2
  • Open source: https://github.com/angular/angular.js

Angular.js

Introduction
  • Data binding
  • Single Page Application (SPA)
  • REST
  • Dependency Injection (DI)
  • MVC

Angular.js

Introduction
DEMO

Angular.js

Composants
  • Module
  • Contrôleurs
  • Formulaires
  • Services et factory
  • Filtres
  • Directives
  • Routeur

Angular.js

Module
  • Contient les différents composants de votre application
  • Toute application contient au moins un module
  • On le déclare dans le code (avec l'attribut ng-app) et dans un fichier Javascript
<html ng-app="myApp">
  <head>
  </head>
  <body>
    <script type="text/javascript" src="angular.js"></script>
    <script type="text/javascript" src="myApp.js"></script>
  </body>
</html>
					
// Création d'un module dans myApp.js
var myAppModule = angular.module('myApp', []);
					

Angular.js

Module
  • Equivalent d'un "main" (point d'entrée de votre application)
  • Tous les composants de votre application seront créés au sein de votre module
  • Le deuxième paramètre est la liste des modules dont votre application dépend
  • Pour récupérer un module sans le créer, il suffit de ne pas préciser le second paramètre
// Création d'un module
var myAppModule = angular.module('myApp', []);

// Récupération du module
var module = angular.module('myApp');

console.log(myAppModule === module); // true
					

Angular.js

Contrôleurs

Angular.js

Contrôleurs
  • Un contrôleur contient la logique (le comportement) associée à votre page HTML (qui représente la vue du modèle MVC)
  • C'est un contrôleur conforme au pattern MVC
  • Un contrôleur angular.js n'est rien d'autre qu'une fonction !
<div ng-controller="myController">
  <p>Ma page HTML</p>
</div>
					
angular.module('myApp')
  .controller('myController', function () {
    // Le code de votre contrôleur !
  });
					

Angular.js

Contrôleurs
  • Pour afficher des données gérées dans votre contrôleur, il faut les partager à la vue
  • Pour partager des données, on utilise l'objet $scope
  • C'est le M du modèle MVC
<div ng-controller="myController">
  <p>Hello {{ name }}</p>
</div>
					
angular.module('myApp')
  .controller('myController', ['$scope', function ($scope) {
    $scope.name = 'world';
  }]);
					

Angular.js

Contrôleurs
  • L'objet $scope a été instancié par Angular.js : notre application ne crée pas d'objets, mais demande à Angular.js de nous les fournir
  • C'est l'injection de dépendance
  • C'est un concept qu'on retrouve dans beaucoup d'autres langages et frameworks
    • Java: Spring, CDI
    • PHP: Symfony

Angular.js

$scope
  • L'objet $scope est un objet très important
    • Il contient les données accessible depuis la page HTML
    • Il hérite (au sens héritage prototypal) de ses scopes parents
    • Il possède des méthodes utiles: $watch ; $on
    • Tout objet $scope hérite forcément du $rootScope
    • Toute application Angular.js possède un (et un seul) $rootscope

Angular.js

$scope
Chaque $scope hérite de son scope parent (défini par l'arborescence du dom)
<div ng-controller="myController">
  <div ng-controller="myOtherContoller">
  </div>
</div>
					
angular.module('myApp')
  .controller('myController', ['$scope', function ($scope) {
    $scope.name = 'world';
  }]);

angular.module('myApp')
  .controller('myOtherController', ['$scope', function ($scope) {
    console.log($scope.name); // world
  }]);
					

Angular.js

$scope
  • Pour afficher les valeurs du scope, le plus simple est d'utiliser les "doubles moustaches"
  • Une autre façon est d'utiliser la directive ng-bind
<div ng-controller="myController">
  Hello {{name}}

  Hello <span ng-bind="name"></span>
</div>
					
angular.module('myApp')
  .controller('myController', ['$scope', function ($scope) {
    $scope.name = 'world';
  }]);
					

Angular.js

$scope
  • La méthode $watch permet d'exécuter du code quand une valeur change
  • Ressemble fortement à Object.observe
angular.module('myApp')
  .controller('myController', ['$scope', function ($scope) {
    $scope.name = 'world';

    $scope.$watch('name', function (newValue, oldValue) {
      console.log(newValue, oldValue);
    });
  }]);
                  

Angular.js

$scope
  • La méthode $on permet d'écouter un évenement provenant d'un autre contrôleur
  • Permet de "dispatcher" des événements
  • Une façon de faire communiquer des contrôleurs (mais pas toujours la bonne façon)
angular.module('myApp')
  .controller('myController', ['$scope', '$rootScope',
    function ($scope, $rootScope) {
      $scope.$on('myEvent', function (event, param1) {
        console.log(param1);
      });

      $rootScope.$broadcast('myEvent', 'foo');
    }
  ]);
					

Angular.js

Formulaires & ng-model
  • Pour récupérer les valeurs saisies dans un formulaire, on utilisera l'attribut ng-model
  • Au fur et à mesure de la saisie, les variables du scope sont mises à jour par Angular.js
  • Si la valeur est mise à jour programmatiquement, la valeur du champ est mise à jour
  • C'est ce qu'on appelle le double binding

Angular.js

Formulaires & ng-model
Exemple
<div ng-controller="myController">
  <form>
    <input type="text" ng-model="name">
    Message: {{ name }}
  </form>
</div>
					
angular.module('myApp')
  .controller('myController', ['$scope', function ($scope) {
    $scope.name = 'hello world';

    $scope.$watch('name', function (newValue) {
      console.log(newValue);
    }):
  }]);
					

Angular.js

Formulaires & ng-model
La directive ng-model est l'une des features les plus importantes d'Angular.js
<div ng-controller="myController">
  <input id="my-input" type="text" ng-model="name">
</div>
					
VS
var myValue = 'foo';

$('#my-input').on('keyup', function (e) {
  myValue = $(this).val();
});

myValue = 'bar';
$('#my-input').val(myValue);
					

Angular.js

Http
  • Angular.js fournit une api pour faire des requêtes HTTP
  • S'interface parfaitement avec une api REST
  • Prend en charge toutes les spécificités des navigateurs
  • Il suffit d'injecter le service $http dans un contrôleur
  • Permet de faire toutes les requêtes "classique"
    • GET
    • POST
    • PUT
    • DELETE

Angular.js

Http
Exemple : GET "/foo"
angular.module('myApp')
  .controller('myController', ['$scope', '$http',
    function ($scope, $http) {
      $http.get('/foo')
        .success(function (data) {
          $scope.data = data;
        })
        .error(function (error) {
          $scope.error = error;
        });
    }
  ]);
					

Angular.js

Http
  • Attention, le résultat est asynchrone
    • Communication synchrone: vous demandez un résultat et l'avez "tout de suite" (i.e vous êtes bloqué tant que la réponse n'est pas là)
    • Communication asynchrone: vous demandez un résultat, mais vous pouvez passez à autre chose et vous serez averti de la réponse une fois disponible
  • On récupère le résultat via un callback de succès
  • On récupère l'erreur via un callback d'erreur

Angular.js

Factory
  • Une factory permet d'extraire des composants ré-utilisables
  • On peut le récupérer dans un contrôleur par injection de dépendance
  • C'est à la factory d'instancier le composant
angular.module('myApp')
  .factory('myComponent', function () {
    return {
      helloWorld: function () {
        console.log('hello world');
      }
    };
  })
  .controller('myController', ['$scope', 'myComponent',
    function ($scope, myComponent) {
      $scope.message = myComponent.helloWorld();
    }
  ]);
					

Angular.js

Factory
  • La factory est exécutée la première fois où le composant est injecté
  • Le composant ne sera créé qu'une et une seule fois (singleton): idéal pour partager des données entre contrôleurs !
  • Idéal pour factoriser du code entre contrôleurs

Angular.js

Service
  • Un service ressemble à une factory avec une différence : l'objet est déjà instancié
  • On définit juste les attributs sur l'objet "this" (qui représente l'objet instancié)
  • Peut être vu comme un raccourci pour écrire une factory
angular.module('myApp');
  .service('myComponent', function () {
    this.helloWorld = function () {
      return 'Hello World';
    };
  })
  .controller('myController', ['$scope', 'myComponent',
    function ($scope, myComponent) {
      $scope.message = myComponent.helloWorld();
    }
  ]);
					

Angular.js

Filtres
  • Un filtre est un composant permettant d'altérer l'affichage d'une valeur
  • Evalué lorsque le DOM est affiché / rafraichi (à chaque fois !)
  • Permet de bien séparer l'affichage de la manipulation des données
  • Un exemple est l'utilisation du filtre angular "date"
<div ng-conroller="myController">
  <Current date: {{ myDate | date:'dd/MM/yyyy' }}>
</div>
					
angular.module('myApp')
  .controller('myController', ['$scope', function ($scope) {
    $scope.myDate = new Date();
  }]);
					

Angular.js

Filtres
  • Angular fournit une collection de filtres prêts à l'emploi
    • date
    • number
    • currency
    • uppercase / lowercase
    • orderBy
    • etc.
  • La documentation est très bien faite !

Angular.js

Filtres
  • Un filtre peut également être utilisé dans un contrôleur
<div ng-conroller="myController">
  Current date: {{ myDate }}>
</div>
					
angular.module('myApp')
  .controller('myController', ['$scope', '$filter',
    function ($scope, $filter) {
      $scope.myDate = $filter('date')(new Date(), 'dd/MM/yyyy');
    }
  ]);
					

Angular.js

Filtres
  • Les filtres peuvent se chaîner (comme un pipe unix)
<div ng-conroller="myController">
  Current date: {{ myDate | date:'dd/MMMMM/yyyy' | uppercase }}>
</div>
					
angular.module('myApp')
  .controller('myController', ['$scope', function ($scope) {
    $scope.myDate = new Date();
  }]);
					

Angular.js

Filtres
  • Ecrire son propre filtre consiste "juste" à écrire une fonction !
<div ng-conroller="myController">
  foo filter {{ myData | foo }}>
</div>
					
angular.module('myApp')
  .controller('myController', function ($scope) {
    $scope.myData = 'hello';
  })
  .filter('foo', function () {
    // On retourne une fonction qui sera exécutée à chaque rafraichissement
    return function (param) {
      return param + ' foo';
    };
  });
					

Angular.js

Directives
  • Les directives représentent une extention du DOM
  • Peut être utilisée comme un attribut ou une nouvelle balise
  • Les attributs ng-controller / ng-app / ng-model sont des directives !

Angular.js

Directives
module.directive('ngBind', function () {
  return function (scope, element, attrs) {
    scope.$watch(attrs.ngBind, function (newValue) {
      element.html(newValue);
    });
  };
});
					

Angular.js

Directives
  • Sujet vaste et compliqué qu'on n'abordera pas plus aujourd'hui
  • Nombreux exemples sur Github (angular-ui, angular-strap)
  • Beaucoup de directives Angular.js (ngBind, ngModel, etc.) sont simples à lire et sont très instructives

Angular.js

Router
  • Le routeur Angular.js est un composant très simple
  • Il suffit de définir les routes disponibles et les templates html associés
  • La page doit contenir un élément avec un attribut ng-view
  • C'est ce bloc qui sera mis à jour à chaque changement de route

Angular.js

Best practices
  • Pas de manipulation du DOM dans un contrôleur : c'est le rôle d'une directive !
  • La customisation de l'affichage doit être fait dans un filtre
  • Gardez vos contrôleurs simple et "petit"
  • Utiliser des services pour factoriser du code et extraire le code "compliqué" des contrôleurs
  • Faites des tests unitaires : jasmine + karma = :)

Angular.js

Exercices
  • Récupérer le zip du tp
  • Lancer le serveur en lançant la commande "node server/app.js"
  • Enregistrer son login
  • Valider avec moi l'exercice
  • Récupérer le mot de passe de validation !

Angular.js

Exercices
Récupérer les tweets en faisant un GET sur "/tweets" Brancher le post d'un tweet Ecrire un filtre pour afficher le login précédé du caractère '@' Capter l'événement 'tweet:new' pour afficher les tweets en temps réel Refactorer l'affichage du tweet en utilisant une directive