Rechercher dans ce blog

mercredi 30 octobre 2013

Initialisation d'AngularJS


AngularJS est une librairie javascript. Pour l'utiliser il faut donc la référencer dans nos pages. Comme souvent il y a deux possibilités : télécharger le fichier et le déposer sur son serveur ou utiliser un CDN. Si avoir le code sous la main peut être pratique pendant la phase de développement, il est beaucoup plus efficace de passer par un CDN dans la phase production (mise en cache, accès rapide, parallélisme des requêtes...).

Vous trouvez le fichier d'AngularJS sur le site. Vous trouvez au même endroit le lien du CDN. Il est conseillé de référencer le lien de la librairie à la fin de la page HTML pour que celle-ci se charge correctement sans avoir à attendre. Mais la différence n'est pas très sensible, d'autant que la mise en cache de la librairie rend cette considération sans objet pour les chargements suivants.

Le chargement de la librairie ne suffit pas pour avoir AngularJS actif sur une page, il faut aussi définir la portion de code qui est concernée. Pour cela il faut placer la directive ngApp dans la balise englobante. Voici donc le code minimal d'une page qui prend en compte AngularJS :

<!doctype html>
<html ng-app>
 <body>
  ...
  <script src="https://ajax.googleapis.com/ajax/libs/
angularjs/1.0.8/angular.min.js"></script>
 </body>
</html>

Ici la directive ngApp a été mise dans la balise html, on veut donc faire agir AngularJS sur toute la page. On aurait pu limiter la portée à une balise enfant. Il n'y a rien de plus à faire pour initialiser AngularJS, c'est la version automatique. La directive provoque l'auto-initialisation d'AngularJS. Il existe aussi une version manuelle si vous voulez agir sur la configuration de démarrage d'Angular. Pour le moment il ne se passe pas grand chose dans notre code. Mais nous allons bientôt animer un peu tout ça !

Vous vous posez peut-être la question de la syntaxe du nom de la directive ngApp. Pourquoi du camelCase qui se transforme en snake_case ? Et bien tout simplement parce que c'est une représentation générique. On invoque les directives en passant en snake_case avec différentes formes possibles : ng:app, ng-app, ng_app, x-ng-click et data-ng-app. Vous avez le choix de la forme, notez toutefois que les validateurs HTML5 préfèrent la forme data-ng-app !

Les expressions


Vous pouvez exécuter une expression directement en utilisant une syntaxe assez répandue dans les moteurs de templates : la double accolade. Il est d'ailleurs un peu abusif de dire qu'on peut avec cette méthode exécuter une expression, parce qu'il y a pas mal de limitations (pas de conditions par exemple). Il faut voir cette possibilité dans le cadre d'AngularJS avec l'optique d'une architecture MVC, comme nous allons le voir progressivement (il y a un billet intéressant sur ce sujet ici). Prenons un exemple simple d'expression (JSFiddle) :
<div ng-app>
 9-5 = {{9-5}}
</div>
L'expression entre les doubles accolades est évaluée et donne le résultat 4. Si vous lancez une page avec ce code et que vous êtes observateur vous pourrez vous rendre compte que le navigateur affiche fugitivement {{9-5}} avant d'afficher le 4. Cela est dû au fait que votre navigateur commence par afficher la page HTML avant de laisser AngularJS évaluer l'expression et en afficher le résultat. Dans la plupart des cas cela n'est pas gênant et ne peut se manifester que sur la première page affichée. Il existe une solution pour éviter cette apparition qui consiste à ne pas utiliser la syntaxe avec les accolades mais une directive ngBind (JSFiddle) :
<div ng-app>
 9-5 = <span ng-bind="9-5"></span>
</div>
Le résultat est exactement le même mais on a plus l'apparition fugitive. Par contre le code est beaucoup moins lisible.

Dans une expression vous pouvez utiliser une propriété d'un objet Javascript, comme par exemple la longueur d'une chaîne de caractères (JSFiddle) :
<div ng-app>
 {{("texte").length}}
</div>
Mais évidemment une expression n'est pas faite normalement pour effectuer un traitement. Pour en savoir plus consultez la documentation officielle

Les filtres


Un filtre sert à mettre en forme le résultat d'une expression. La syntaxe est simple, il suffit de faire suivre l'expression du signe "|" suivi du nom du filtre.

Filtre uppercase

Pas besoin de grande explication pour ce filtre qui se contente de mettre tout en majuscules (JSFiddle) :
{{"Essai" | uppercase}}

Filtre lowercase

Il existe évidemment le filtre inverse qui met tout en minuscules (JSFiddle) :
{{"Essai" | lowercase}}

Filtre number

Ce filtre met en forme un nombre et retourne un texte avec la mise en forme souhaitée. Par défaut il est conservé 3 décimales, pour une valeur différente il faut le préciser. Vous trouverez des explications précises dans la documentation. Voici un exemple de mise en oeuvre (JSFiddle) :
<div ng-app>
 Nombre de base : 263.21584<br>
 Filtre number par défaut : {{263.21584 | number}}<br>
 Filtre number avec deux décimales : {{263.21584 | number:2}}<br>
</div> 

Filtre date

Ce filtre met en forme une date et retourne un texte avec la mise en forme souhaitée.Vous trouverez des explications précises dans la documentation. Le possibilités sont très nombreuses. Voici un exemple de mise en oeuvre (JSFiddle) :
<div ng-app>
 Date 2013-10-29 avec filtre date 'dd/MM/yyyy' : 
{{'2013-10-29' | date:'dd/MM/yyyy'}}<br>
 Date en millisecondes 1383001200000 avec filtre date 'dd/MM/yyyy' : 
{{'1383001200000' | date:'dd/MM/yyyy'}}
</div>

Filtre currency

Ce filtre met en forme un nombre comme valeur monétaire. Par défaut on a évidemment des $ mais il est possible d'utiliser son propre symbole. Vous trouverez des explications précises dans la documentation. Voici un exemple de mise en oeuvre  (JSFiddle) :
<div ng-app>
 Valeur de base : 230.25<br>
 Filtre currency par défaut : {{230.25 | currency}}<br>
 Filtre currency avec Euro (€) : {{230.25 | currency:'€ '}}<br>
</div>
Il existe évidemment d'autres filtres disponibles mais vous avez compris le principe, nous verrons sans doute d'autres filtres ultérieurement...
AngularJS est un framework Javascript (donc totalement placé côté client) qui étend les possibilités du HTML de façon déclarative. Il est élégant, puissant et adaptable. Il exonère le développeur du bidouillage habituel au niveau du DOM. Il respecte le modèle MVC. Il sait établir des liaisons de données pour rendre une page réactive à un changement au niveau du modèle et réciproquement. Il n'est pas facile à maîtriser mais c'est le prix à payer pour sa richesse. Ce blog est destiné à vous lancer dans l'aventure de ce framework de façon progressive et cohérente. Il est loin d'épuiser le sujet et se contente de montrer quelques possibilités d'AngularJS.

AngularJS est novateur, complet, et permet réellement de parler d'application côté client. HTML n'a pas été pensé à la base pour du contenu dynamique, et rendre les pages réactives et adaptables requiert pas mal de code, l'utilisation d'une librairie spécialisée comme jQuery, ou d'un framework. Il existe des concurrents à AngularJS, en particulier ember qui en est assez proche. Derrière AngularJS il y a toute la puissance de Google et peut-être aussi un rapprochement avec les Web Components et l'intéressant projet Polymer.

Il existe de très nombreuses références sur ce framework sur Internet, peut-être même trop pour vraiment s'y retrouver, et pratiquement exclusivement en langue anglaise. La principale source d'information est évidemment le site d'AngularJS qui propose un tutoriel, un guide du développeur et une référence complète des API. En langue Française il faut noter l'excellent blog de Thierry Chatel. Il y a également un regroupement de ressources ici et une proposition de parcours didactique . Mon blog a pour seul objectif de vous mettre le pied à l'étrier pour intégrer peu à peu les notions indispensables pour utiliser judicieusement ce framework. Il est organisé de façon progressive, il faut donc le parcourir dans l'ordre. N'hésitez pas à faire les exercices proposés, c'est ainsi qu'on apprend ! 

Je ne suis pas un spécialiste de ce framework et j'ai dû piocher dans beaucoup de pages pour trouver certains renseignements et certaines explications. Mon seul objectif est de faire une synthèse en Français de tout ça pour vous faire gagner du temps. Pour chaque exemple que je présenterai je mettrai un lien vers une page JSFiddle pour que vous puissiez facilement faire des tests. Je suis évidemment ouvert à toute critique ou suggestion pour corriger ou améliorer mon approche !