Mes premiers pas avec AngularJS

angularjs

Ça fait longtemps que je voulais m’y mettre, j’utilise habituellement Backbone pour les besoins similaires.

C’est l’occasion d’introduire une nouvelle série d’articles sur ce blog : Mes premiers pas.

En parcourant la documentation je me suis rendu compte assez rapidement qu’AngularJS n’a rien à voir avec Backbone, il est beaucoup plus complet et aborde les choses différemment. Mais surtout, AngularJS est magique, on s’approche un peu de l’état d’esprit de Ruby On Rails qui pré-mâche le travail du développeur et bouscule la manière de développer une application web.

Pour moi cela signifie 2 choses :

  1. Code plus propre et maintenable : Les bonnes pratiques sont accessibles facilement, il suffit de lire les documentations pour produire du code de qualité.
  2. Meilleure testabilité : On se focalise sur les choses qui comptent vraiment, AngularJS s’occupe du bas niveau pour nous.

Concrètement, comment ça fonctionne ?

Je vous conseille de visionner cette vidéo qui introduit AngularJS via un exemple vraiment très simple :

Petit résumé de la vidéo :

On peut demander à AngularJS d’être actif sur une portion de code via l’attribut ng-app à placer sur la balise de notre choix, si on veut qu’il soit actif sur la page entière, il faut simplement le mettre sur la balise <html> :

&lt;html ng-app&gt;

On voit également qu’on peut définir un modèle directement dans le HTML via l’attribut ng-model :

&lt;input type=&quot;text&quot; ng-model=&quot;yourName&quot; placeholder=&quot;Enter a name here&quot;&gt;

A chaque fois qu’une touche sera pressée dans ce champ, le modèle sera mis à jour avec sa valeur.

Grâce au data-binding, on peut se brancher à un modèle dans le HTML. Il suffit d’utiliser les doubles accolades :  {{ }} et y ajouter le nom du modèle.

Pour l’exemple de la vidéo :

&lt;h1&gt;Hello {{ yourName }}!&lt;/h1&gt;

Le HTML de ce bout de code est automatiquement recompilé par AngularJS à chaque fois que le modèle yourName est mis à jour. Ce qui explique pourquoi avec 0 ligne de javascript, lorsque l’on met à jour le champ texte, sa valeur est automatiquement reportée dans le HTML.

Testez par vous-mêmes !.

Allons un peu plus loin :

Tout d’abord, je vous invite à regarder cette seconde vidéo de 10 minutes pour mieux comprendre la suite.

Pour tester je vais créer une mini application web étape par étape : un moteur de recherche de répertoires GitHub.

J’ai créé une page HTML simple avec Twitter Bootstrap initialisée avec ng-app comme on l’a vu plus haut.

Ensuite dans un nouveau fichier repos.js, j’ai créé un controller GitHubReposController :

// Création du controller
function GitHubReposController($scope, $http) {

    // Initialisation du tableau répertoires
    $scope.repos = [];

    // On va chercher dans l'API github pour peupler le tableau
    $http.get('https://api.github.com/legacy/repos/search/onegameamonth')
        .success(function(data) {
            $scope.repos = data.repositories;
        });

}

Maintenant il faut lier le controller au HTML avec l’attribut ng-controller :

&lt;div ng-controller=&quot;GitHubReposController&quot;&gt;
    &lt;h1&gt;GitHub Repos&lt;/h1&gt;
    &lt;li ng-repeat=&quot;repo in repos&quot;&gt;
        {{repo.name}}
    &lt;/li&gt;
&lt;/div&gt;

&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;repos.js&quot;&gt;&lt;/script&gt;

Comme on a bindé la liste des répertoires (repos) sur le scope ($scope.repos), on peut y accéder directement dans la vue.

L’attribut ng-repeat permet de boucler sur un tableau. Dans notre cas ça voudrait dire :

for(var repo in repos) {
    // Affichage
}

Essayez la démo (source), vous verrez la liste des répertoires GitHub contenant le mot clé onegameamonth.

J’ai voulu aller un peu plus loin en permettant de chercher n’importe quel mot clé et ordonner les résultats.

Pour ça, il faut modifier le controller :

// Création du controller
function GitHubReposController($scope, $http) {

    // Initialisation du tableau répertoires
    $scope.repos = [];
    $scope.keyword = &quot;onegameamonth&quot;;

    $scope.search = function() {
        // On va chercher dans l'API github pour peupler le tableau
        $http.get('https://api.github.com/legacy/repos/search/'+$scope.keyword)
            .success(function(data) {
                $scope.repos = data.repositories;
            });
    };

    $scope.search();

    $scope.sort = 'name';
}
  1. J’assigne un mot clé ($scope.keyword) par défaut lorsque l’on charge la page.
  2. Je mets le get dans une fonction search qui sera appelée par un formulaire.
  3. J’assigne un tri ($scope.sort) par nom par défaut.

Ensuite il reste à modifier la vue :

&lt;div ng-controller=&quot;GitHubReposController&quot;&gt;
    &lt;h1&gt;GitHub Repos Search Engine&lt;/h1&gt;
    &lt;form ng-submit=&quot;search()&quot;&gt;
        &lt;input type=&quot;text&quot; ng-model=&quot;keyword&quot; size=&quot;30&quot; placeholder=&quot;search&quot;&gt;
        &lt;input type=&quot;submit&quot; value=&quot;Search&quot;&gt;
    &lt;/form&gt;
    &lt;h2&gt;{{repos.length}} results.&lt;/h2&gt;
    &lt;p&gt;
        Sort by
        &lt;a href=&quot;&quot; ng-click=&quot;sort = 'size'; reverse=!reverse&quot;&gt;Size&lt;/a&gt; |
        &lt;a href=&quot;&quot; ng-click=&quot;sort = 'forks'; reverse=!reverse&quot;&gt;Forks&lt;/a&gt; |
        &lt;a href=&quot;&quot; ng-click=&quot;sort = 'name'; reverse=!reverse&quot;&gt;Name&lt;/a&gt; |
        &lt;a href=&quot;&quot; ng-click=&quot;sort = 'owner'; reverse=!reverse&quot;&gt;Owner&lt;/a&gt; |
        &lt;a href=&quot;&quot; ng-click=&quot;sort = 'created_at'; reverse=!reverse&quot;&gt;Creation Date&lt;/a&gt;
    &lt;/p&gt;
    &lt;li ng-repeat=&quot;repo in repos | orderBy:sort:reverse&quot;&gt;
        &lt;div&gt;&lt;a href=&quot;https://github.com/{{repo.owner}}/{{repo.name}}&quot;&gt;{{repo.name}}&lt;/a&gt;, &lt;i&gt;{{repo.description}}&lt;/i&gt;&lt;/div&gt;
        &lt;div&gt;Created by &lt;a href=&quot;https://github.com/{{repo.owner}}&quot;&gt;{{repo.owner}}&lt;/a&gt; at {{repo.created_at | date:'fullDate'}}&lt;/div&gt;
        &lt;div&gt;Size: {{repo.size}} - Forks: {{repo.forks}} - Followers: {{repo.followers}} - Watchers: {{repo.watchers}}&lt;/div&gt;
    &lt;/li&gt;
&lt;/div&gt;
&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;repos.js&quot;&gt;&lt;/script&gt;
  1. J’ai créé un formulaire en y ajoutant l’attribut ng-submit avec la valeur search(), ce qui aura pour effet d’appeler la fonction $scope.search() dans mon controller à chaque envoi du formulaire.
  2. J’affiche le nombre de résultats en comptant les occurrences du tableau repos : {{repos.length}}
  3. J’ajoute des liens pour ordonner les résultats avec en attribut ng-click
  4. dans l’attribut ng-click j’assigne une nouvelle valeur à sort, ce qui aura pour effet de modifier l’ordre d’affichage.
  5. Je rajoute l’ordre d’affichage dans le np-repeat grâce au filtre orderBy.

Maintenant, nous avons un vrai moteur de recherche, voici une petite démo (source).

Conclusion

Personnellement, je trouve que cette façon de concevoir une application web est très élégante et plus simple que les autres voies habituelles. Dès que j’en aurai l’occasion j’utiliserai AngularJS pour pousser son utilisation un peu plus loin afin de témoigner de son vrai potentiel et de ses faiblesses. Je vous ferai certainement part de mes retours d’expérience à ce moment-là.

En attendant j’ai récolté quelques ressources pour approfondir mes connaissances que j’aimerais partager avec vous :

Have fun!

10 thoughts on “Mes premiers pas avec AngularJS”

  1. “AngularJS est magique” . Assez d’accord avec ça, c’est l’impression que j’ai aussi en l’utilisant depuis peu. A voir maintenant comment toute cette machinerie fonctionne pour mettre en place de bonnes pratiques, mais sur le coté documentation et com ils ne sont pas trop mal..

  2. J’ai fait les mêmes constats que ceux que tu décris dans ton article. Etant développeur Rails, j’ai beaucoup apprécié l’approche d’Angular et la façon dont on bind dans les vues HTML. Concernant l’effet “magie”, je pense c’est qu’on attend d’un bon framework MVC, c’est à dire se concentrer sur la couche métier, et laisser le bas niveau au framework.
    Personnellement j’ai fais le choix d’Angular pour le développement d’une petite application iOS / Android en PhoneGap, j’en suis plus que satisfait.

Leave a Reply

Your email address will not be published. Required fields are marked *