02. Création de l'application AngularJS

Notre projet étant initié, nous allons maintenant coder avec angular afin de créer notre première application. Nous mettrons en avant le partern MVC en ajoutant un mini modèle et un controller à notre application.

Déclaration de l'application

Après avoir inclus le fichier JS correspondant à angular, nous avons maintenant accès à une varibale globale qui nous permet d'intéragir avec le Framework.

Nous allons donc créer un fichier app.js dans notre répertoire src et y mettre le code correspondant, sachant que notre application s'appelle showthequeApp:

'use strict';

var app = angular.module('showthequeApp', []);

'use strict' permet de forcer l'écriture de javascript plus propre; c'est une bonne pratique de le mettre dans chaque fichier JS.

Ensuite, il va falloir brancher norte application sur notre HTML. Pour ce faire, utilisons la directive ng-app. Nous reviendrons plus en détail sur les directives ultérieurement. Pour faire simple, se sont des attributs HTML qui permettent de brancher des composants Angular afin de rendre le HTML dynamique. N'oublions pas d'inclure le script que nous venons d'écrire: app.js:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ShowTheque - AngularJS</title>
    <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body ng-app="showthequeApp">
    <h1>ShowTheque - AngularJS</h1>


    <script src="../node_modules/jquery/dist/jquery.min.js"></script>
    <script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>

    <script src="../node_modules/angular/angular.min.js"></script>
    <script src="../node_modules/angular-route/angular-route.min.js"></script>

    <script src="app.js"></script>

</body>
</html>

Si on lance l’application, en apparence nous ne verrons aucun changement. Mais Angular et sa puissance sont maintenant bien présents, nous pourrions commencer à jouer avec. Mais, je préfère directement passer par l’ajout d’un controller.

Ajout d'un controller

Les controller (notions qu’on retrouve dans d’autres Framework) sont en quelques sortes les chefs d’orchestre entre la vue (ici notre fichier index.html) et le model (données de notre application). Le controller va dans un sens récupérer les données de de notre application (souvent par le biais de service) puis demander à la vue de les afficher. Et dans l’autre sens il va récupérer les évènements de la vue (par exemple le clic sur un bouton) et agir en conséquant.

Créons notre premier controller, que nous appellerons MainController grâce à la fonction controller de l’object angular. Pour pouvoir commencer à tester nous allons dedans ajouter un object user qui contiendra une propriété nom et age :


var moi = {
    nom:'manu',
    age:25
};

app.controller('MainController', function(){
    var vm = this;
    vm.user = moi;
});

Puis nous allons l'utiliser dans notre vue grâce à la directive ng-controller:

<body ng-app="showthequeApp">
    <h1>ShowTheque - AngularJS</h1>

    <div ng-controller="MainController as main">

        <div>Je m'appelle {{main.user.nom}} et mon age est de {{main.user.age}}</div>

        <div>Changer de nom <input type="text" ng-model="main.user.nom" /></div>

    </div>


    <!-- [scripts] --> 

</body>

La variable vm dans le controller ou main dans la vue sont la même chose et s’appelle le scope. C’est une sorte de ViewModel qui est partagé entre la vue et le controller et qui est automatiquement mis à jour des deux côté. Si je modifie le nom dans le champ texte, il sera mis à jour dans la variable vm du controller puis cette modification sera répercuté dans la vue au niveau de la phrase Je m’appelle..., c’est ce qu’on appelle le bindings bidirectionnel.

Le double accolade {{ }} sont la partie templating de Angular qui permet d’incorporer du JavaScript dans le HTML, nous verrons ça en détail plus bas.

La direcive ng-model permet de lier notre champ texte au model afin qu'il soit automatiquement mis à jour.

Et c’est là qu’on commence à apercevoir la puissance d’Angular si on imagine ce qu’il aurait fallu écrire en JavaScript pour faire cette simple mise à jour.

L'injection de dépendance

L'injection de dépendance permet d'ajouter des services inclus dans Angular (ou que nous avons créée) dans notre controller afin de l'enrichir. En effet le controller sert seulement à orchestrer, le code métier ne doit pas être écrit dedans. Par exemple si nous avions une page qui affiche une liste de personne nous aurions un service UserManagerService qui serai injecté dans notre controller et qui nous fournirai une méthode d’accès aux personnes.

Pour le moment nous allons rester simple et utiliser le service $interval fourni par Angular qui permet d’appeler une fonction à intervalle régulier. Avec nous allons incrémenter l’age toute les secondes.


var moi = {
    nom:'manu',
    age:25
};

app.controller('MainController', ['$interval', function($interval){
    var vm = this;
    vm.user = moi;

    $interval(function (){
        vm.user.age++;
    }, 1000);
}]);

Nous avons transformé le deuxième paramètre de la fonction controller afin d'y mettre un tableau. Le dernier élément de ce tableau sera toujours la fonction correspondant à notre controller et les éléments précédents les différents services à injecter dans le controller. Angular alimentera les paramètres de la fonction avec ces services ce qui nous y donnera accès dans le controller.

Les templates

Les templates sont des portions de JavaScript écrite entre double accolade {{ }}. Il n’est possible d’écrire du JavaScript complet (par exmple utiliser des if/else) mais seulement des opérations simple. il ne provoque pas d'érreur en cas d'appel à une propriété qui n'existe pas.

<div>{{ 1 + 2}}</div> <!-- 3 -->
<div>{{main.user.age + 5}}</div> <!-- 30 -->
<div>{{ 'nom: ' + main.user.nom}}</div> <!-- nom: manu -->
<div>{{ main.user.prenom }}</div> <!-- pas d'erreur, le div sera juste vide -->

On peut aussi ajouter des filter afin de modifier le contenu du template, comme par exemple passer tout le texte en majuscule. Nous verrons ça dans une prochaine leçon.

Il est aussi possible dans certain cas d'utiliser la directive ng-bind, les deux notations suivantes sont équivalentes:

<div>{{main.user.nom}}</div>
<div ng-bind="main.user.nom"></div>

La notations des controllers

Il existe deux façons majeures de déclarer des controllers (avec des variantes), celle de l’exemple précèdent qui est la plus récente et qu’on appelle ControllerAs.

Une autre qui était la seule avant Angular 1.2 permet de faire la même chose mais se note différemment aussi bien au niveau du JS que du HTML. Je vous la monte car elle est encore utilisé, l’équivalant est :


var moi = {
    nom:'manu',
    age:25
};

app.controller('MainController', ['$scope', '$interval', function($scope, $interval){
    $scope.user = moi;

    $interval(function (){
        $scope.user.age++;
    }, 1000);
}]);

Dans la partie controller, le scope doit être injecté, et on l’utilise directement à la place du this.

<body ng-app="showthequeApp">
    <h1>ShowTheque - AngularJS</h1>

    <div ng-controller="MainController">

        <div>Je m'appelle {{user.nom}} et mon age est de {{user.age}}</div>

        <div>Changer de nom <input type="text" ng-model="user.nom" /></div>

    </div>


    <!-- [scripts] --> 

</body>

Dans la partie vue, on ne déclare pas de variable correspondant au scope, et on travail directement avec.

La première notation est à privilégier car elle offre plusieurs avantages, notamment une meilleure visibilité dans le cas de controller imbriqués.