Vues et Binding AngularJS

Pour le pattern MVC/MVVM, une vue a pour rôle d’afficher les données à l’utilisateur. Elle dispose du modèle pour récupérer les données à afficher et transmet les actions de l’utilisateur aux contrôleurs.

Pour AngularJS, une vue se traduit par une page HTML, ou plus précisément un template de page HTML. Le modèle, initialisé par le contrôleur, est transmis par l’objet $scope à la vue. AngularJS s’occupe ensuite de fusionner le template avec les données du modèle pour générer la vue à afficher à l’utilisateur.

1. Binding

Pour pouvoir afficher une donnée du modèle dans la vue, il faut passer par du binding.

Le principe de binding est de synchroniser une donnée du modèle et l’affichage de cette donnée. Il existe trois types de bindings gérés par AngularJS. Le binding one-way permet de mettre à jour la vue lorsque le modèle change. De manière identique au binding one-way, le two-way permet de mettre à jour la vue dès que le modèle change. Par contre, ce binding permet aussi de mettre à jour le modèle lorsque la vue change, c’est-à-dire lorsque l’utilisateur modifie par exemple la valeur d’un champ d’un formulaire HTML. Enfin, le binding one-time permet d’afficher une donnée du modèle dans la vue puis de désactiver la relation de binding.

Afficher une donnée

Pour pouvoir afficher la valeur d’une propriété du modèle dans la vue, il faut utiliser la syntaxe {{ nomPropriété }}, où nomPropriété correspond au nom de la propriété. À l’affichage de la vue, le marqueur précédent sera remplacé par la valeur de la propriété du modèle.

L’exemple précédent affiche la valeur de la propriété value du modèle dans une balise HTML p via la syntaxe {{ }}.

L’attribut ng-bind permet aussi d’afficher une donnée, en renseignant le nom de la propriété du modèle à afficher comme valeur de l’attribut. À l’affichage de la vue, AngularJS va insérer la valeur de la propriété du modèle dans le contenu de la balise.

L’exemple précédent affiche la valeur de la propriété value du modèle dans une balise HTML p via la syntaxe ng-bind.

Le fonctionnement de ces deux syntaxes est le même, tout comme le résultat. La seule différence intervient lors de l’affichage de la page.

Lorsque le navigateur va afficher la page, il va rendre visuellement le HTML puis AngularJS sera exécuté. Si la syntaxe {{ }} est utilisée, entre le moment où le navigateur aura affiché la page et le moment où AngularJS aura interprété la vue et appliqué le binding, l’utilisateur verra la chaîne de caractères {{ value }}. Après l’interprétation de la vue, le marqueur sera remplacé par la valeur liée.

Dans le cas de l’attribut ng-bind, avant l’interprétation d’AngularJS, rien ne sera affiché. La valeur bindée apparaîtra après l’interprétation.

Ces deux syntaxes permettent de faire du binding one-way, c’est-à-dire que si une modification est effectuée par le contrôleur sur le modèle, cette modification sera automatiquement répercutée sur la vue. Par contre, si la valeur est modifiée au niveau de la vue, elle ne sera pas prise en compte par le modèle. Ce binding correspond au scénario où l’on souhaite afficher une donnée du modèle sans qu’elle soit modifiable par l’utilisateur.

Récupérer les données renseignées par l’utilisateur

Dans les scénarios où il est nécessaire de récupérer des informations renseignées par un utilisateur, à travers un formulaire HTML par exemple, le binding two-way doit être utilisé.

Pour en profiter avec AngularJS, il faut utiliser l’attribut ng-model en renseignant la propriété du modèle à binder.

L’exemple précédent correspond à un formulaire de connexion. Les inputs HTML sont bindés aux propriétés username et password du modèle. Dès que l’utilisateur renseignera ces champs, le modèle sera mis à jour. Le contrôleur aura accès aux données renseignées via les propriétés $scope.username et $scope.password.

Grâce à ce binding et à l’attribut ng-model, la vue et le modèle sont synchronisés, que les modifications soient effectuées dans la vue ou dans le contrôleur.

Par défaut, la mise à jour du modèle après modification de la vue est effectuée dès que l’utilisateur renseigne une nouvelle information. Par exemple, sur un champ HTML input de type text, la mise à jour du modèle sera effectuée à chaque nouveau caractère saisi ou à chaque caractère supprimé. Il est possible de personnaliser ce comportement en utilisant l’attribut ng-model conjointement à l’attribut ng-model-options.

Ce dernier attribut attend comme valeur un objet JavaScript pouvant être composé des propriétés updateOn, debounce et getterSetter. La propriété updateOn permet de spécifier sur quel évènement JavaScript la mise à jour du modèle est déclenchée.

L’exemple précédent utilise l’attribut ng-model-options sur les champs Login et Password pour définir la mise à jour du modèle après l’évènement blur, correspondant à la perte de focus du champ.

La propriété debounce de ng-model-options définit un temps d’attente, en millisecondes, avant de déclencher la mise à jour du modèle.

L’exemple précédent utilise l’attribut ng-model-options sur les champs Login et Password pour définir un temps d’attente de 500 millisecondes avant la mise à jour du modèle.

Enfin, la propriété getterSetter permet d’activer le mode getter/setter sur le binding.

L’exemple précédent utilise l’attribut ng-model-options sur le champ Login pour activer le mode getter/setter.

Le contrôleur de l’exemple précédent enrichit le modèle avec une propriété password et avec une fonction username de type getter/setter. Si cette fonction est appelée sans paramètre, elle renverra la valeur stockée, sinon elle modifiera cette valeur.

L’intérêt principal de cette option est de pouvoir stocker la donnée dans le modèle de manière différente à l’affichage dans la vue.

Afficher une donnée puis désactiver la relation de binding

AngularJS propose un troisième type de binding : le one-time binding. Le principe de ce binding est d’afficher une propriété du modèle dans la vue, puis de désactiver la relation de binding. De cette manière, si la valeur change dans le modèle, la vue ne sera pas mise à jour.

Pour profiter de ce type de binding, il faut utiliser la syntaxe {{::nomPropriété}}, où nomPropriété correspond au nom de la propriété. À l’affichage de la vue, le marqueur précédent sera remplacé par la valeur de la propriété du modèle.

L’exemple précédent affiche la valeur de la propriété value du modèle dans une balise HTML p via la syntaxe {{::}}. Si la propriété du modèle change, la vue ne sera pas mise à jour.

L’avantage de ce binding est de ne pas surcharger la page avec des bindings sur des propriétés qui ne changeront pas. Cette optimisation sera vue plus en détail dans le chapitre Notions avancées.