Syntaxe des templates Angular 2

Nous avons déjà rencontré des templates Angular dans plusieurs chapitres précédents. Dans cet article, nous allons présenter la syntaxe Angular en détail.

Le template joue le rôle d'une vue ; en termes simples, c'est la partie affichée à l'utilisateur.

  • HTML
  • Expression d'interpolation
  • Expressions de template
  • Instructions de modèle
  • Syntaxe de liaison
  • Liaison de propriété
  • Liaison d'attribut, de classe et de style HTML
  • Liaison d'événement
  • Liaison de données bidirectionnelle avec NgModel
  • Directives intégrées
  • * et <template>
  • Variables de référence de modèle
  • Propriétés d'entrée et de sortie
  • Opérateurs d'expression de modèle

HTML

HTML est le "langage" des modèles Angular. À l'exception de l'élément <script>, qui est désactivé, tous les autres éléments HTML sont pris en charge. Par exemple :

<h1>Ma première application Angular</h1>


Expression d'interpolation

Le format de syntaxe des expressions d'interpolation est :{{ ... }}。

Les expressions d'interpolation peuvent insérer la chaîne calculée dans le HTML et peuvent également être utilisées comme valeurs d'attribut.

<h3> {{title}} <img src="{{imageUrl}}" style="height:30px"> </h3>

Expressions de template

{{ ... }}Il s'agit en fait d'une expression de modèle. Angular l'évalue et la convertit en une chaîne pour la sortie.

L'exemple suivant additionne deux nombres :

<!-- "La somme de 1 + 1 est 2" --> <p>La somme de 1 + 1 est {{1 + 1}}</p>

Nous pouvons utilisergetVal()pour obtenir la valeur de cette expression :

<div class="example"> <div class="example_code"> [mycode3 type="html"] <!-- "4" --> <p>{{1 + 1 + getVal()}}</p>

Les expressions de modèle sont similaires à JavaScript. De nombreuses expressions JavaScript sont également des expressions de modèle valides, mais pas toutes.

Les expressions JavaScript suivantes sont interdites :

  • Expressions d’affectation (=,+=,-=...)
  • opérateur new
  • with;ou'expressions enchaînées
  • Opérations d’incrémentation et de décrémentation (++et--) Parmi les autres différences notables avec la syntaxe JavaScript :
  • Les opérateurs bit à bit ne sont pas pris en charge (|et&)
  • Les opérateurs dans les expressions de modèle, tels que|et?.etc., ont reçu de nouvelles significations

Liaison de propriété

La liaison de propriété de modèle peut définir une propriété d’un élément de vue à une expression de modèle.

La liaison de propriété la plus courante définit la propriété d'un élément sur la valeur d'une propriété de composant. Dans l'exemple suivant, la propriété src de l'élément image est liée à la propriété imageUrl du composant :

<img [src]="imageUrl">

Désactiver un bouton lorsque le composant est isUnchanged (inchangé) :

<button [disabled]="isUnchanged">Le bouton est désactivé</button>

Définir les attributs de la directive :

<div [ngClass]="classes">[ngClass] lié à la propriété classes.</div>

Définir une propriété d'un composant personnalisé (un moyen important de communication entre les composants parents et enfants) :

<user-detail [user]="currentUser"></user-detail>

Liaison d'attribut, de classe et de style HTML

La syntaxe de template fournit une forme spéciale de liaison de données unidirectionnelle pour les scénarios qui ne sont pas bien adaptés à la liaison de propriété.

Liaison d'attributs

Lorsqu'un élément n'a aucune propriété à lier, utilisez la liaison d'attributs HTML.

Considérez des attributs tels que ARIA, SVG et colspan/rowspan dans les tableaux. Ce sont uniquement des attributs. Ils n'ont aucune propriété correspondante à lier.

L'exemple suivant lèvera une erreur :

<tr><td colspan="{{1 + 1}}">Trois-Quatre</td></tr>

Nous obtiendrons cette erreur :

Template parse errors:
Can't bind to 'colspan' since it isn't a known native property

模板解析错误:不能绑定到'colspan',因为它不是已知的原生属性

Comme l'indice le dit,<td>L'élément n'a pas decolspanpropriété. Mais les expressions d'interpolation et la liaison de propriété ne peuvent définir que lapropriété, plutôt qu'un attribut, donc la liaison d'attribut de balise HTML est nécessaire pour créer et lier des attributs similaires.

La liaison d'attribut de balise HTML est syntaxiquement similaire à la liaison de propriété, mais la partie entre crochets n'est pas le nom de propriété d'un élément ; au lieu de cela, elle est constituée d'un préfixe attr. et du nom d'un attribut de balise HTML, puis la valeur de l'attribut de balise HTML est définie via une expression qui peut être évaluée en une chaîne. Par exemple :

<table border=1> <tr><td [attr.colspan]="1 + 1">Un-Deux</td></tr> <tr><td>Cinq</td><td>Six</td></tr> </table>

Liaison de classes CSS

Avec la liaison de classes CSS, nous pouvons ajouter et supprimer des noms de classes CSS de l'attribut class d'un élément.

La liaison de classes CSS est syntaxiquement similaire à la liaison de propriétés. Mais la partie entre crochets n'est pas le nom de propriété d'un élément ; elle se compose plutôt d'un préfixe de classe, suivi d'un point (.), puis d'un nom de classe CSS. Les deux dernières parties sont facultatives. Par exemple :[class.class-name] 。

L'exemple suivant montre comment ajouter et supprimer la classe "special" via la liaison de classes CSS :

<!--Définition standard de classe de style HTML--> <div class="bad curly special">Bad curly special</div> <!--Réinitialiser ou remplacer les classes de style via la liaison--> <div class="bad curly special" [class]="badCurly">Bad curly</div> <!--Ajouter ou supprimer la classe de style special en fonction de la valeur d'une propriété--> <div [class.special]="isSpecial">Ce style est spécial</div>

Liaison de style

Grâce à la liaison de style, vous pouvez définir des styles en ligne. La liaison de style est syntaxiquement similaire à la liaison de propriété, mais la partie entre crochets n'est pas le nom d'une propriété d'un élément ; la liaison de style se compose de style. suivi du nom de la propriété de style CSS, par exemple : [style.style-property].

<button [style.color] = "isSpecial ? 'red': 'green'">Rouge</button> <button [style.background-color]="canSave ? 'cyan': 'grey'" >Enregistrer</button> <!--Liaison de style avec unités--> <button [style.font-size.em]="isSpecial ? 3 : 1" >grand</button> <button [style.font-size.%]="!isSpecial ? 150 : 50" >petit</button>

Les noms de propriétés de style peuvent être en kebab-case (font-size) ou en camelCase (fontSize).


Liaison d'événement

Dans la liaison d'événement, Angular répond au flux de données correspondant—de la cible de vue vers la source de données—en écoutant les actions de l'utilisateur telles que les événements clavier, les événements souris, les événements tactiles, etc.

La syntaxe de la liaison d'événement se compose, à l'intérieur des parenthèses à gauche du signe égal,événement cibleet, à l'intérieur des guillemets à droite,instruction de template.

Par exemple, l'exemple suivant est une liaison d'événement qui écoute l'événement de clic du bouton. À chaque clic de souris, il appelle la méthodeonSave()du composant.

<button (click)="onSave()">Enregistrer</button>

Le nom entre parenthèses—par exemple (click)—identifie l'événement cible. Dans l'exemple suivant, la cible est l'événement click du bouton.

<button (click)="onSave()">Enregistrer</button>

Vous pouvez également utiliser la forme avec le préfixe on- :

<button on-click="onSave()">À l'enregistrement</button>

Liaison de données bidirectionnelle avec NgModel

Lors du développement de formulaires de saisie, le résultat souhaité est à la fois d'afficher les données du composant dans le formulaire et de mettre à jour les données du composant lorsque l'utilisateur effectue des modifications.

Voici un exemple d'utilisation de[(NgModel)]pour implémenter une liaison bidirectionnelle :

<input [(ngModel)]="currentUser.firstName">

[] implémente le flux de données du composant vers le template, () implémente le flux de données du template vers le composant, et la combinaison des deux [()] implémente une liaison bidirectionnelle.

Utilisation de la syntaxe avec préfixe :

<input bindon-ngModel="currentUser.firstName">

Directives intégrées

Les directives intégrées d'Angular incluent NgClass, NgStyle, NgIf, NgFor, NgSwitch, etc.

NgClass

Ajoutez ou supprimez dynamiquement des classes CSS en effectuant une liaison avec NgClass.

<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >Cette div est grande.</div>

NgStyle

NgStyle, grâce à une liaison à un objet de contrôle clé:valeur, permet de définir de nombreux styles en ligne simultanément.

setStyles() { let styles = { // Nom de la propriété CSS 'font-style': this.canSave ? 'italic' : 'normal', // italique 'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal 'font-size': this.isSpecial ? '24px' : '8px', // 24px }; return styles; }

En ajoutant une liaison de propriété NgStyle qui appelle setStyles, vous pouvez définir les styles de l'élément en conséquence :

<div [ngStyle]="setStyles()">Les styles de cette div sont en italique, en graisse normale et en taille très grande (24px).</div>

NgIf

En liant la directive NgIf à une expression considérée comme vraie, vous pouvez ajouter un élément et ses enfants à l'arbre DOM.

<div *ngIf="currentUser">Bonjour,{{currentUser.firstName}}</div>

Inversement, une liaison à une expression considérée comme fausse supprimera l'élément et ses enfants de l'arbre DOM. Par exemple :

<!--Comme la valeur de isActive est false, User Detail ne figure pas dans l'arbre DOM.--> <user-detail *ngIf="isActive"></user-detail>

NgSwitch

Lorsque vous devez afficher conditionnellement un arbre d'éléments parmi un ensemble d'arbres d'éléments possibles, NgSwitch est nécessaire. Angular n'ajoutera au DOM que l'élément sélectionné. Par exemple :

<span [ngSwitch]="userName"> <span *ngSwitchCase="'Zhang San'">Zhang San</span> <span *ngSwitchCase="'Li Si'">Li Si</span> <span *ngSwitchCase="'Wang Wu'">Wang Wu</span> <span *ngSwitchCase="'Zhao Liu'">Zhao Liu</span> <span *ngSwitchDefault>Long Da</span> </span>

La [directive] qui sert de directive parenteNgSwitchest lié à une expression qui renvoie la valeur du switch. Dans l’exemple, cette valeur est une chaîne, mais elle peut être une valeur de n’importe quel type. La directive parenteNgSwitchcontrôle un groupe de<span>éléments enfants. Chaque<span>est soit lié à une expression avec une valeur correspondante, soit marqué comme le cas par défaut. À tout moment, au plus un de ces spans apparaîtra dans le DOM. Si la valeur correspondante de ce span est égale à la valeur du switch, Angular 2 ajoute ce<span>span au DOM. Si aucun span ne correspond, Angular 2 ajoute le span par défaut au DOM. Angular 2 supprime et détruit tous les autres spans.

Trois directives qui coopèrent :

  • ngSwitch : lié à une expression qui renvoie la valeur du switch
  • ngSwitchCase : lié à une expression qui renvoie la valeur correspondante
  • ngSwitchDefault : un attribut utilisé pour marquer l’élément par défaut*, mais devrait plutôt utiliser la liaison de propriété, tandis que ngSwitchCase et ngSwitchDefault doivent être précédés par*。

NgFor

Cette directive est nécessaire lorsque vous devez afficher une liste composée de plusieurs éléments. Comme dans l’exemple ci-dessous, NgFor est appliqué à un bloc HTML.

<div *ngFor="let user of users">{{user.fullName}}</div>

NgFor peut également être appliqué à un élément de composant, par exemple :

<user-detail *ngFor="let user of users" [user]="user"></user-detail>

La directive ngFor prend en charge un index facultatif qui va de 0 à la longueur du tableau pendant l'itération.

Cet index peut être capturé via une variable d'entrée de modèle et utilisé dans le modèle. L'exemple ci-dessous capture l'index dans une variable nommée i.

<div *ngFor="let user of users; let i=index">{{i + 1}} - {{user.fullName}}</div>

NgForTrackBy

La directive ngFor peut parfois avoir de mauvaises performances, en particulier dans les grandes listes. Un petit changement, une suppression ou un ajout à un élément entraînera des opérations DOM en cascade.

Par exemple, lors de l'actualisation des contacts en les récupérant à nouveau depuis le serveur, la liste actualisée peut contenir de nombreux contacts (voire tous) qui étaient affichés auparavant. Mais en ce qui concerne Angular, il ne sait pas lesquels existaient auparavant, il ne peut donc qu'effacer l'ancienne liste, écarter ces éléments DOM et reconstruire une nouvelle liste avec de nouveaux éléments DOM.

Pour résoudre ce problème, vous pouvez utiliser une fonction de suivi pour éviter cet inconvénient. La fonction de suivi indique à Angular : nous savons que deux objets ayant le même user.id correspondent au même contact. Par exemple :

trackByUsers(index: number, user: User){return user.id}

Ensuite, définissez la directive NgForTrackBy sur cette fonction de suivi :

<div *ngFor="let user of users; trackBy:trackByUsers">({{user.id}}) {{user.fullName}}</div>

La fonction de suivi n'empêche pas tous les changements DOM. Si la propriété utilisée pour déterminer s'il s'agit du même contact change, l'élément DOM sera mis à jour ; sinon, cet élément DOM est laissé tel quel. L'interface de liste devient plus fluide et plus réactive.


Variables de référence de modèle

Les variables de référence de template sont des références à des éléments DOM ou à des directives dans le template.

Elles peuvent être utilisées sur des éléments DOM natifs et sur des composants Angular — en fait, elles fonctionnent avec n'importe quel composant web personnalisé.

Nous pouvons référencer des variables de référence de template sur le même élément, des éléments frères ou n'importe quels éléments enfants.

Voici deux exemples de création et d'utilisation de variables de référence de template :

<!--phone fait référence à l'élément input et transmet `value` au gestionnaire d'événements--> <input #phone placeholder="numéro de téléphone"> <button (click)="callPhone(phone.value)">Appeler</button> <!--fax fait référence à l'élément input et transmet `value` au gestionnaire d'événements--> <input ref-fax placeholder="numéro de fax"> <button (click)="callFax(fax.value)">Fax</button>

Le préfixe (#) de "phone" signifie que nous allons définir une variable nommée phone.

Autres extensions