Rechercher dans ce blog

samedi 2 novembre 2013

Les contrôleurs


Nous avons vu quelques exemples d'utilisation d'AngularJS avec une approche un peu "magique". Tout se passe dans les coulisses, on s'est contenté d'utiliser des directives et des expressions. On a vu également qu'il se construit un scope pour renseigner la vue. Au niveau de cette vue nous avons adopté une démarche qui ne respecte pas trop le MVC parce que nous avons initialisé des valeurs, ce qui est normalement la tâche du contrôleur au niveau du modèle. Nous allons donc mettre maintenant en oeuvre un contrôleur pour nous rendre plus conforme au modèle MVC avec un premier exemple simple (JSFiddle) :
<div ng-app ng-controller="controleur">
  <p>{{texte}}</p>
  <script>
    function controleur($scope) {
      $scope.texte = 'Bonjour !';
    }
  </script>
</div>
Le contrôleur est une fonction Javascript qui comporte un paramètre. Celui-ci est important parce qu'il correspond à une référence du scope, on fait donc une injection de dépendance. Le contrôleur ici crée et initialise la propriété texte du scope. Une expression dans la vue permet ensuite l'affichage de cette valeur. Le contrôleur est déclaré avec la directive ngController, cette déclaration a aussi pour effet d'implicitement créer un scope pour ce contrôleur. L'emplacement de la directive ngController n'est pas anodin parce que le scope correspondant va concerner tout ce qui se trouve à l'interieur de la balise correspondante.

Pour avoir une visualisation de cette organisation voici un petit schéma inspiré de la documentation :


 

La directive ngChange


Nous avons vu ci-dessus un premier exemple élémentaire de contrôleur pour comprendre l'architecture du système. On a vu que le contrôleur peut créer le modèle et renseigner le scope. Une autre fonction du contrôleur est aussi d'ajouter des comportements. Imaginez que vous avez une zone de saisie de texte et que vous voulez connaître en permanence le nombre de mots contenus dans le texte saisi. Voici comment réaliser cela (JSFiddle) :
<div ng-app ng-controller="controleur">
  <textarea ng-model="texte" ng-change="changement()"></textarea>
  Nombre de mots : {{nombre}}
  <script>
    function controleur($scope) {
      $scope.nombre = 0;
      $scope.changement = function() {
        $scope.nombre = $scope.texte.split(/\b\w+\b/).length-1;
      };
    }
  </script>
</div>
Le code utilise une nouvelle directive : ngChange. Elle permet la mise en place d'une écoute de l'évenement de changement dans le contrôle. Donc dès que le texte change au niveau du contrôle textarea on va appeler la fonction désignée changement(). Cette fonction compte le nombre de mots et met à jour la propriété nombre du scope, l'expression {{nombre}} est alors actualisée.

Pour avoir une visualisation de cette organisation voici un petit schéma inspiré de la documentation :


Un petit TP


On va faire un nouveau point de ce qu'on a vu avec un petit exercice. Le but est de construire encore un tableau mais cette fois de personnes avec leur nom et leur âge. On prévoit deux zones de texte pour entrer les informations. On veut que le tableau s'actualise à mesure :

Nom : Age :
Personnes
Nom Age
{{personne.nom}} {{personne.age}}

Vous trouverez ma solution dans ce JSFiddle. La seule difficulté réside dans le fait que cette fois la méthode du contrôleur comporte des paramètres. La déclaration ngSubmit permet d'intercepter la soumission du formulaire et de l'orienter sur la méthode du contrôleur. Nous n'avons rien prévu dans notre code concernant la validité des données saisies, si ce n'est de préciser le type des zones, en particulier number pour l'âge. Si vous regardez le code généré vous allez trouver de nouvelles classes ng-valid, ng-dirty et ng-valid-number. Ce sont des classes de travail d'AngularJS. On se rend compte qu'elles ont à voir avec la validation des données. Entrez autre chose qu'un nombre pour l'âge et vous verrez que la valeur ne s'inscrit pas dans le tableau. La classe ng-valid-number se transforme alors en ng-invalid-number. Tout ça est géré par le contrôleur de formulaire d'AngularJS.

1 commentaire: