Décorateur

Référence : https://www.tektutorialshub.com/angular/angular-decorators/

Le décorateur est une fonctionnalité Typescript et ne fait toujours pas partie du Javascript. Il est encore au stade de proposition.

Pour activer les décorateurs Angular, nous devons ajouter les experimentalDecorators au fichier tsconfig.json. La nouvelle commande ng l'ajoute automatiquement pour nous.

Le but des décorateurs Angular est de stocker des métadonnées sur une classe, une méthode, une propriété ou un paramètre. Lorsque vous configurez un composant, vous fournissez des métadonnées pour cette classe qui indiquent à Angular que vous avez un composant et que ce composant a une configuration spécifique.

Nous appliquons le décorateur en utilisant la forme @expression, où expression est le nom du décorateur.

Par exemple, l'AppComponent doit savoir où trouver son modèle. Pour ce faire, nous utilisons le paramètre templateUrl de la directive @Component. Le décorateur @Component accepte également les valeurs pour styleUrls, encapsulation, changeDetection, etc., qu'Angular utilise pour configurer le composant.

@Component({
  templateUrl: './app.component.html',
 
})
export class AppComponent {
  title = 'app';
}

Evénement

Pour lier à un événement, la syntaxe est simple :  un nom d’événement cible entre parenthèses à gauche, le signe égal et une instruction de modèle entre guillemets à droite.

Exemple : 

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

Directive

Les directives sont des classes qui ajoutent un comportement supplémentaire aux éléments des applications Angular. On utilise les directives intégrées d'Angular pour gérer les formulaires, les listes, les styles et ce que les utilisateurs voient.

Types de directive Détails
Components Utilisé avec un template. Le type le plus commun de directive. Ce n'est rien d'autre qu'une simple classe qui est décorée avec le décorateur @component.
Attribute directives

Change l'apparence ou le comportement d'un élément, d'un composant ou d'une autre directive. Les directives d'attribut les plus communes :

NgStyle, NgClass

Structural directives

Change la mise en page du DOM en ajoutant ou en supprimant des éléments du DOM.

On peut importer toutes les directives structurelles d'un seul coup en important CommonModule : 

import { CommonModule } from '@angular/common';

 

Sinon, on peut importer seulement la directive structurelle dont on a besoin :

 import { NgIf } from '@angular/common';

 

ng-template

ng-template fonctionne sur le modèle des templates HTML. C'est à dire qu'un template ne sera pas visible par défaut. Il ne le deviendra que si on l'instancie spécifiquement.

Un exemple de ng-template :

<ng-template #titleTpl>
  <h2>Titre par défaut</h2>
</ng-template>
<div *ngIf="table.title else titleTpl">
  <h2>{{ table.title }}</h2>
</div>

Dans le code ci-dessus, le template ne sera affiché que si la propriété table.title est fausse.

Autre exemple de template avec sa version raccourcie :

<ng-template [ngIf]="cards.length > 0">
  <div><h2>Cartes</h2></div>
</ng-template>

Cette syntaxe est toujours raccourcie comme ceci :

<div *ngIf="cards.length > 0"><h2>Cartes</h2></div>

Le caractère * indique que l'on instancie un template

Formulaires

Formulaires basés sur les templates 

Les formulaires basés sur les templates sont ajoutés via FormsModule.

Ex :

import {FormsModule} from "@angular/forms";

@Component({...})
export class App { }

@NgModule({
    declarations: [App],
    imports: [BrowserModule, FormsModule],
    bootstrap: [App]
})
export class AppModule {}

Notez qu'en incluant simplement ce FormsModule dans votre application, Angular appliquera déjà implicitement une directive NgForm à chaque élément de modèle HTML <form>, à moins que vous n'annotiez l'élément de formulaire avec l'attribut ngNoForm (plus à ce sujet plus tard).

Notez que chaque contrôle de formulaire a la directive qui lui est appliquée. Cette directive se liera à l'élément HTML correspondant, dans ce cas les deux champs de saisie prénom et mot de passe.

La directive ngModel gardera une trace de la valeur saisie par l'utilisateur à chaque touche enfoncée, et elle gardera également une trace de l'état de validité de ce contrôle de formulaire particulier uniquement.

La directive parent ngForm interagira alors avec toutes ses directives ngModel enfants et construira un modèle de l'ensemble du formulaire, avec toutes ses valeurs de champ et ses états de validité.

 

Input

@Input() permet à un composant parent de mettre à jour les données dans le composant enfant.

Décorateur qui marque un champ de classe en tant que propriété d'entrée et fournit des métadonnées de configuration. La propriété d'entrée est liée à une propriété DOM dans le modèle. Lors de la détection des modifications, Angular met automatiquement à jour la propriété data avec la valeur de la propriété DOM.

@Input() bankName: string;

Par exemple, imaginons qu'un composant parent Cards ait pour template :

<div *ngFor="let card of cards">
  <co-card [card]="card"></co-card>
</div>

Alors le composant enfant Card devra importer les données du composant parent de la manière suivante :

export class CardComponent {
  @Input({ required: true }) card!: CardModel;
}

L' assertion non-nulle "!" permet de s'assurer que la propriété card n'est pas nulle. 

Interpolation

L'interpolation fait référence à l'incorporation d'expressions dans un texte balisé. Par défaut, l'interpolation utilise les doubles accolades {{  }} comme délimiteurs.

Pour illustrer le fonctionnement de l'interpolation, considérons un composant angulaire qui contient une variable currentCustomer :

currentCustomer = 'Maria' ;
Utilisez l'interpolation pour afficher la valeur de cette variable dans le modèle de composant correspondant :

<h3>Current customer: {{ currentCustomer }}</h3>

Angular remplace currentCustomer par la valeur de la chaîne de caractères qui correspond à la propriété du component, dans notre exemple : "Maria".

L'interpolation est utilisée pour afficher simplement une donnée en HTML, comme l'affichage d'un titre ou d'un nom.

Installation de package

Il est facile d'ajouter des packages pour ajouter des fonctionnalités à Angular. Par exemple pour l'ajout de bootstrap et font-awesome :

npm install --save-exact bootstrap@5.3.0 font-awesome

Output

@Output() permet à un composant enfant d'envoyer des données à un composant parent.

Par exemple, si un composant enfant veut transmettre des données à un composant parent lors d'un clic sur un de ses élément html, on utilisera un code du type :

import { Component, Input, Output, EventEmitter } from '@angular/core';
...
export class CardComponent {
 
  clicked = () => {
    this.titleClicked.emit("Titre cliqué");
  }
  @Output() titleClicked = new EventEmitter();
}

Bien sûr la méthode "clicked()" ne sera appelée que si un écouteur de click sur le template a été mis en place. Par ailleurs, le composant parent devra utiliser cet événement custom pour que ce code ait du sens

Property-binding

Le property-binding nous permet de lier une propriété d'un objet DOM, par exemple la propriété "hidden", à une valeur de données. 

Par exemple le code suivant ne fonctionnera pas correctement :

<button class="primary" type="button" disabled={{isDisable}}>Search</button>

Il faudra lui préférer le code suivant :

<button class="primary" type="button" [disabled]="isDisable">Search</button>

Explication : l'interpolation va toujours transformer la valeur en chaîne de caractères alors que le "property-binding" comprend qu'il doit gérer un type spécifique de données (ici un boolean). Donc lorsque l'on doit manipuler autre chose que des chaînes de caractères, il faut utiliser le "property-binding".

A noter que l'on peut parfaitement remplacer l'interpolation par du property-binding.

<h3>Current customer: {{ currentCustomer }}</h3>

devient

<h3>Current customer: <span [textContent]="currentCustomer"></span></h3>

NgFor directive

La directive principale ngFor nous permet de créer des listes et des tableaux de présentation de données dans nos modèles HTML. Prenons par exemple les données suivantes. La directive ngForOf est généralement utilisée sous la forme abrégée *ngFor. Syntaxe : 

<tr *ngFor="let hero of heroes">
  <td>{{hero.name}}</td>
</tr>

Cette directive sous-entend que la variables heroes est définie est qu'elle est de type tableau, par exemple :

const HEROES = [
    {id: 1, name:'Superman'},
    {id: 2, name:'Batman'},
    {id: 5, name:'BatGirl'},
    {id: 3, name:'Robin'},
    {id: 4, name:'Flash'}
];

NgModules

Les NgModules configurent l'injecteur et le compilateur et aident à organiser ensemble les éléments connexes.

Un NgModule est une classe marquée par le décorateur @NgModule. @NgModule prend un objet de métadonnées qui décrit comment compiler le modèle d'un composant et comment créer un injecteur au moment de l'exécution. Il identifie les propres composants, directives et canaux du module, en rendant certains d'entre eux publics, via la propriété exports, afin que les composants externes puissent les utiliser. @NgModule peut également ajouter des fournisseurs de services aux injecteurs de dépendance d'application.

Services et Injection de dépendance

L'injection de dépendances est le mécanisme qui gère les dépendances des composants d'une application et les services que d'autres composants peuvent utiliser.

Système de template

Le système de template offre une syntaxe complète pour afficher des parties statiques et dynamiques. Plus précisément, le système permet le binding de données, de propriétés, dévénements avec pour principales syntaxes :

  • {{ }} - interpolation
  • [ ] - binding de propriété
  • ( ) - binding d'événement
  • # - déclaration de variable
  • * - directives structurelles

Services Angular

Les services Angularvous permettent de séparer les données et les fonctions de l'application Angular qui peuvent être utilisées par plusieurs composants de votre application. Pour être utilisé par plusieurs composants, un service doit être rendu injectable. Les services qui sont injectables et utilisés par un composant deviennent des dépendances de ce composant. Le composant dépend de ces services et ne peut pas fonctionner sans eux.

Standalone Component

Référence : https://angular.io/guide/standalone-components

Les composants, les directives et les canaux peuvent désormais être marqués comme autonomes. Les classes Angular marquées comme autonomes (standalone) n'ont pas besoin d'être déclarées dans un NgModule (le compilateur angulaire signalera une erreur si vous essayez).

Les composants autonomes spécifient directement leurs dépendances au lieu de les obtenir via NgModules. Par exemple, si PhotoGalleryComponent est un composant autonome, il peut importer directement un autre composant autonome ImageGridComponent.

Variable locale

Avec le caractère #, on peut créer une variable locale qui sera une référence vers un élément du DOM. Ex :

<input type="text" #firstname>

Cette variable pourra être utilisée dans le template :

{{ firstname.value }}

Zone

 Les modifications sont automatiquement détectées par le framework et appliquées au modèle et à la vue. La détection de changement utilise désormais un concept nommé "zones".