Introduction à AngularJs

On parle depuis quelques années de web applications et plus particulièrement de single page applications. Les single page applications sont des applications qui s'exécutent depuis une unique page. Pour que ça fonctionne, du code javascript est exécuté sur cette page.

Concrêtement, ce programme javascript va manipuler le DOM. Comme vous le savez, les pages web sont écrites en HTML; c'est un langage par balise qui défini une structure, aussi appelé l'arbre DOM

Pour la suite, il vaut mieux que vous ayez des notions d'HTML et de javascript.

JQuery, la préhistoire

Il y a fort longtemps, le principal framework utilisé sur les pages web était le JQuery. C'était fort pratique mais sans rigueur, le code devenait rapidement un sacré sac de noeuds. Le JQuery permet de manipuler directement les éléments du DOM. Un petit exemple vaut mieux que de longs discours.

<!DOCTYPE html>  
<html>  
  <head>
    <meta charset="utf-8">
    <title>Un exemple avec JQuery</title>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
  </head>
  <body>
    <h1>Hey !</h1>
    <span>Cliquez-moi</span>
    <script>
        $("span").on("click", function () {
            $("h1").html("Yeah!");
        });
    </script>
  </body>
</html>  

Ouvrez ce ficher dans votre navigateur internet (ctrl+o), ou allez directement à la page de test (https://jsfiddle.net/Le35xgvu/)

Comportement

Quand on clique sur Cliquez-moi, le titre change.

Petite explication:

La première balise script permet de charger JQuery. La seconde balise est notre programme. Ce dernier intercepte un clique sur "Cliquez-moi" et transforme le titre en "Yeah!". En détail, on sélectionne la balise <span></span>, on intercepte tout clique dessus pour exécuter une fonction dite anonyme. Dans cette dernière, on sélectionne la balise <h1></h1> et on change le contenu par le texte Yeah!

AngularJs

Le programme de départ

Angular JS est un autre framework avec une autre approche : on ne trafique plus le DOM; on laisse AngularJs s'en occuper. Nous on ne fait que décrire le comportement voulu. Si l'on reprends l'exemple précédent, lors du clique, on ne va pas sélectionner la balise <h1></h1> pour y modifier le contenu. On va variabiliser le contenu de la balise <h1></h1>. Ensuite, au clique, on modifie la variable. Et hop, l'exemple :

<!DOCTYPE html>  
<html>  
  <head>
    <meta charset="utf-8">
    <title>Un exemple avec Angularjs</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
  </head>
  <body data-ng-app data-ng-init="titre='Hey'">
    <h1>{{titre}}</h1>
    <span data-ng-click="titre='Yeah!'">Cliquez-moi</span>
  </body>
</html>  

https://jsfiddle.net/pdjs24d9/

Vous avez vu, la balise <body></body> s'est vu décorer de deux attributs:

  • Le premier, data-ng-appindique à angularjs, que notre application se trouve dans cette balise
  • Le second, data-ng-init="titre='Hey'"permet d'initialiser une variable titre avec la valeur Hey

Vous remarquez ensuite, que la variable titre est entre moustaches {{titre}}. Cela indique à AngularJs d'afficher le contenu de cette variable. C'est pratique pour commencer, mais rapidement on choisira une autre écriture <h1 data-ng-bind="titre"></h1> Car le principal inconvénient de cette écriture, est que le temps que l'application se charge, les moustaches sont affichées à l'écran.

Et enfin, le dernier point, l'attribut data-ng-click="titre='Yeah!'". C'est assez explicite.

On passe la première vitesse ?

Vous allez me dire: "C'est bien gentil, mais faire une application web qui fait juste ça, c'est pas persuasif!"
Et je vous réponds: "C'est pas faux"

Nous allons refaire notre exemple du clique qui modifie le titre en plus propre.

Avant tout, on va commencer par se préparer une structure de fichier; parce qu'avant tout, faut être un minimum rigoureux, et être propre. Commencer un projet de patachon vous mènera vers le mur.

app  
 |--app.js
 |--app.controller.js
index.html  

Avec le premier fichier, app.js, nous allons introduire la notion de modules. Tout est organisé en modules. Chaque module peux avoir des dépendances vers d'autres modules. Généralement, on ne déclare qu'un module. Editez le fichier app/app.js et copiez le code suivant:

/* app.js */

// Déclaration de notre module
angular.module("MyApp", []);  

Dans le second fichier, nous allons déclarer un contrôleur (à l'intérieur de notre module). Le contrôleur est la première entité AngularJs. Il y en a d'autres, on le verra plus tard. Dans ce contrôleur, nous allons décrire le comportement de notre page. Quelques règles que je me suis fixé, et que je vous conseille de suivre :

  • Un fichier par contrôleur
  • Un seul contrôleur par fichier
  • Le nom d'un contrôleur commence toujours par une majuscule et se termine toujours par Ctrl
  • le nom de fichier d'un contrôleur se termine toujours par .controller.js
/* app.controller.js */

angular.module("MyApp").controller("MainCtrl", function ($scope) {  
    "use strict";

    $scope.title = "Hey";

    $scope.click = function() {
        $scope.title = "Yeah!"
    };
});

Tient ! c'est quoi cette variable $scope ? C'est une variable lié au dom, dans toute la partie couverte par ce contrôleur. Elle est injectée par AngularJs dans notre contrôleur. Lorsque l'on passe $scope en paramètre de notre contrôleur, AngularJs l'injecte. C'est ce qu'on appelle l'auto-injection. Ce qu'il faut savoir, c'est que, dans notre fichier HTML, toutes les variables, fonctions auquelles nous faisons référence font partie du scope.

Et maintenant, passons à notre fichier html

<!DOCTYPE html>  
<html>  
  <head>
    <meta charset="utf-8">
    <title>Un exemple avec Angularjs</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
    <script src="app/app.js"></script>
    <script src="app/app.controller.js"></script>
  </head>
  <body data-ng-app="MyApp" data-ng-controller="MainCtrl">
    <h1 data-ng-bind="title"></h1>
    <span data-ng-click="click()">Cliquez-moi</span>
  </body>
</html>  

https://jsfiddle.net/qbcm3rwu/

Remarquez, que l'attribut data-ng-appfait référence à notre module. On déclare aussi notre contrôleur avec data-ng-controller="MainCtrl"

Comme on le disait juste avant, la variable title et la fonction click() sont dans le scope; on peut donc les utiliser directement dans notre HTML.

Le scope

C'est une notion très importante dans le framework AngularJs. Tout ce que l'on veut référencer dans le fichier HTML doit être dans le scope. Mais sachez qu'il n'y a pas toujours qu'un seul scope. Il y en a plein. Pour commencer, à chaque contrôleur, on retrouve un scope. Les scopes sont même hiérarchisés. un scope peut avoir des enfants et des parents. Et le plus important:

Lors de la création d'un scope enfant, le scope parent est cloné. En d'autres terme, lorsqu'AngularJs crée un scope enfant, il le fait en clonant le scope parent.

Pour illustrer cette notion de scope, nous allons prendre un autre exemple et introduire une nouvelle notion : la directive. une directive est une entité AngularJs qui décrit un comportement lorsqu'un attribut (ou une balise) est ajouté dans l'HTML. Nous allons voir la directive data-ng-repeat

Modifiez le contrôleur pour y insérer un tableau de valeurs

/* app.controller.js */

angular.module("MyApp").controller("MainCtrl", function ($scope) {  
    "use strict";

    $scope.table = [
        "trucs",
        "bidules"
    ];

    $scope.title = "Hey";

    $scope.click = function() {
        $scope.title = "Yeah!"
    };
});

et le fichier HTML

<!DOCTYPE html>  
<html>  
  <head>
    <meta charset="utf-8">
    <title>Un exemple avec Angularjs</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
    <script src="app/app.js"></script>
    <script src="app/app.controller.js"></script>
  </head>
  <body data-ng-app="MyApp" data-ng-controller="MainCtrl">
    <h1 data-ng-bind="title"></h1>
    <span data-ng-click="click()">Cliquez-moi</span>
    <ul>
        <li data-ng-repeat="element in table" data-ng-bind="element"></li>
    </ul>
  </body>
</html>  

https://jsfiddle.net/zr29zck4/1/

Magique ! Nous avvons affiché une liste contenant:

  • trucs
  • bidules

Comment ça marche ? data-ng-repeat va créer autant de balise <li></li> qu'il n'y a d'éléments dans notre tableau. Pour chacune de ces balises <li></li>, AngularJs va créer un scope enfant en y injectant l'élément du tableau.

Sapristi ! Ca ne marche pas !

Ben oui, va falloir débugger quand ça ne marche pas. Pour commencer, je vous conseille fortement d'utiliser, comme navigateur Chrome (ou Chromium).

Ensuite, vous devez installer une extension appelée Battarang (https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk)

Vous y êtes ? rechargez votre page et ouvrez la console développeur (F12). Faites un clique droit sur Hey et faites Inspecter. Vous voyez sur quel element HTML vous êtes. allez dans l'onglet console et tapez $scope puis retour à la ligne. Yeah ! vous pouvez afficher le contenu de votre scope. Vous remarquez que vous trouvez, dans le scope, title, click() et table

C'est de cette manière que vous débuggerez la plupart de vos applications.

Maintenant, faites un clique droit sur trucs, puis, dans la console, tapez $scope.element; la valeur de element pour cette ligne est affiché; vous êtes dans le scope de la première ligne du data-ng-repeat