Angular, 1ers pas (la base de la base)

VoilĂ , je me dĂ©cide Ă  me mettre sĂ©rieusement (mais en douceur) Ă  Angular. Je vais donc apprendre au fur et Ă  mesure et rĂ©diger Ă  chaque fois ce que j’en ai retirĂ© et compris. Je “mettrais” ensuite tout ça au “mĂȘme endroit” dans un e-book par ici http://e-books.github.io/je.decouvre.angular/.

Si vous pensez que je me trompe, que vous n’ĂȘtes pas d’accord, que vous avez des idĂ©es 
 n’hĂ©sitez pas, une PR sur le repository de l’e-book sera la bienvenue. Gardez seulement Ă  l’esprit que c’est Ă  destination des dĂ©butants, donc je n’attaque pas l’écriture des directives avant un moment.

Préparation

Pré-requis

  • nodejs
  • npm
  • bower

Dans un répertoire créez les fichiers suivants (à la racine) :

bower.json

{
  "name": "books",
  "version": "0.0.0",
  "dependencies": {
    "angular" : "1.2.16"
  }
}

.bowerrc

{
  "directory": "public/bower_components"
}

Ensuite créez un répertoire public avec le fichier suivant dans ce répertoire:

public/index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>livres</title>
</head>
<body>

  <script src="bower_components/angular/angular.min.js"></script>
  <script src="js/main.js"></script>

</body>
</html>

Ensuite créez un sous-répertoire js dans public avec le fichier suivant dans ce répertoire:

public/js/main.js

// Foo ...

Ensuite lancez la commande bower install pour télécharger la librairie Angular.

Nous avons donc la structure de projet suivante:

votre_projet/
├── public/
|   ├── bower_components/ /* angular est par ici */
|   ├── js/      
|   |    └── main.js
|   └── index.html
├── bower.json
└── .bowerrc

Architecture minimale d’une application Angular

Une application Angular nécessite au minimum :

  • un module principal : le code js qui reprĂ©sente votre application
  • au moins un contrĂŽleur (en js) qui contiendra les traitements
  • au moins une vue qui est tout simplement du code html contenu dans votre page
  • des directives qui sont des attributs des tags html et qui servent Ă  faire le lien entre les vues et les contrĂŽleurs

Plus concrÚtement en code ça donnerait ceci :

Module principal

Dans main.js définissons le module de notre application booksApp

var booksApp = angular.module("booksApp", []);

Nous devons expliquer à Angular que nous “lions” notre page à booksApp, donc dans index.html, modifier le tag <body> de la façon suivante avec la directive ng-app :

<body ng-app="booksApp">

Un ContrĂŽleur

Dans main.js dĂ©finissons le ContrĂŽleur MainCtrl que l’on rattache Ă  notre application booksApp:

var MainCtrl = booksApp.controller("MainCtrl", function($scope) {
  
})

$scope est la variable de contexte qui va contenir des informations accessibles et modifiables Ă  la fois par le contrĂŽleur et la vue.

Modifions notre contrîleur pour qu’il puisse nous fournir une liste de livres:

var MainCtrl = booksApp.controller("MainCtrl", function($scope) {
  $scope.books = [
      {title:"Backbone c'est de la balle", description:"tutorial bb", level:"trĂšs bon"}
    , {title:"React ça dépote", description:"se perfectionner avec React", level:"bon"}
    , {title:"J'apprends Angular", description:"from scratch", level:"débutant"}
  ];
})

Une Vue

Et modifions notre code html de la façon suivante :

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>livres</title>
</head>
<body ng-app="booksApp">

    <div ng-controller="MainCtrl">
      <h2>Livres</h2>
      <div ng-repeat="book in books">
        <h4>{{book.title}}</h4>
        <p>{{book.description}} - level <b>{{book.level}}</b></p>
        <hr>
      </div>
    </div>

  <script src="bower_components/angular/angular.min.js"></script>
  <script src="js/main.js"></script>

</body>
</html>

Nous avons donc utilisé 2 directives supplémentaires :

  • <div ng-controller="MainCtrl"> pour lier notre contrĂŽleur au <div>
  • <div ng-repeat="book in books"> pour parcourir le contenu de $scope.books

Et du templating pour afficher tout ça :

<h4>{{book.title}}</h4>
<p>{{book.description}} - Niveau <b>{{book.level}}</b>

Vous pouvez dÚs maintenant afficher votre page avec la liste des livres en ouvrant index.html dans votre navigateur préféré.

Ajouter un formulaire de saisie pour modifier les livres

Modifier les livres

Commençons par ajouter 2 propriétés levels, selectedBook et une méthode selectBook

var MainCtrl = booksApp.controller("MainCtrl", function($scope) {
  $scope.books = [
      {title:"Backbone c'est de la balle", description:"tutorial bb", level:"trĂšs bon"}
    , {title:"React ça dépote", description:"se perfectionner avec React", level:"bon"}
    , {title:"J'apprends Angular", description:"from scratch", level:"débutant"}
  ];

  $scope.levels = [
    "trÚs bon", "bon", "débutant"
  ];

  $scope.selectedBook = null;

  $scope.selectBook = function(book) {
    $scope.selectedBook = book;
  }

})

Et dans notre vue ajoutons le formulaire suivant :

<div ng-controller="MainCtrl">
  <!-- mon joli formulaire -->
  <hr>
  <div>
    <input ng-model="selectedBook.title">
    <input ng-model="selectedBook.description">
    <div>
      <select id="inputType"
              ng-model="selectedBook.level"
              ng-options="level for level in levels"></select>
    </div>
  </div>
  <hr>
  <!-- fin de mon joli formulaire -->

Et modifions la portion de code précédente en y ajoutant la directive ng-click="selectBook(book)"

  <h2>Books</h2>
  <div ng-repeat="book in books" ng-click="selectBook(book)">
    <h4>{{book.title}}</h4>
    <p>{{book.description}} - Niveau <b>{{book.level}}</b>
    <hr>
  </div>
</div>

Donc Ă  chaque fois que nous “cliquerons” sur la ligne d’un livre la mĂ©thode selectBook(book) du contrĂŽleur sera appelĂ©e et mettra Ă  jour la propriĂ©tĂ© $scope.selectedBook avec le livre sĂ©lectionnĂ©.

Et le formulaire de saisie sera mis Ă  jour automatiquement grĂące aux directives :

  • ng-model="selectedBook.title"
  • ng-model="selectedBook.description"
  • ng-model="selectedBook.level"
  • ng-options="level for level in levels"

Vous pouvez dÚs maintenant essayer, et vous allez vous apercevoir que lorsque vous sélectionnez un livre, le formulaire se met à jour, et lorsque vous modifiez les données dans le formulaire, la liste se met à jour automatiquement de maniÚre assez magique, je dois bien le reconnaßtre.

Ajouter un livre

C’est encore plus simple, ajoutez la mĂ©thode createBook Ă  votre contrĂŽleur :

$scope.createBook = function() {
  $scope.books.push({
    title : "This is a new Book",
    description : "...",
    level: "???"
  });
}

Puis ajouter un bouton (<a href="# " ng-click="createBook()">Ajouter un livre</a>) dans votre page en dessous de la liste des livres:

<div ng-controller="MainCtrl">
  <hr>
  <div>
    <input ng-model="selectedBook.title">
    <input ng-model="selectedBook.description">
    <div>
      <select id="inputType"
              ng-model="selectedBook.level"
              ng-options="level for level in levels"></select>
    </div>
  </div>
  <hr>
  <h2>Livres</h2>
  <div ng-repeat="book in books" ng-click="selectBook(book)">
    <h4>{{book.title}}</h4>
    <p>{{book.description}} - level <b>{{book.level}}</b>
    <hr>
  </div>
  <!-- le bouton est ici !!! -->
  <hr>
  <a href="# " ng-click="createBook()">Ajouter un livre</a>
  <hr>
</div>

Le bouton est un lien (pourquoi pas?) avec une directive ng-click="createBook()" qui permettra d’appeler la mĂ©thode createBook() de notre contrĂŽleur lorsque l’on clique sur le lien et d’ajouter un nouveau livre que vous pourrez ensuite modifier (ok mon workflow n’est pas forcĂ©ment au top mais ça vous donne l’idĂ©e).

Vous pouvez tester :)

C’est tout pour aujourd’hui. Demain je vous montre comment faire “plus propre” en utilisant les services, les factories et si ça se passe bien on attaque la partie “ajax” et serveur. Et vous aurez les codes sources en prime et l’ebook à jour.

A demain :)

blog comments powered by Disqus

Related posts