Appearance
Comment utiliser ControlValueAccessor ?
Pour utiliser ControlValueAccessor pour créer une palette de couleurs sur Angular, vous pouvez suivre ces étapes :
- Vous devez créer un composant de palette de couleurs qui implémente l'interface
ControlValueAccessor
. Cela vous permet de contrôler la valeur du composant et de déclencher des événements lorsque la valeur change. Voici un exemple de code pour un composant de palette de couleurs :
ts
import { Component, forwardRef, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-color-picker',
standalone: true,
template: `
<div class="color-picker">
@for (color of colors ; track color) {
<div
[style.background]="color"
class="color"
(click)="selectColor(color)"
[class.selected]="color === selectedColor"
></div>
}
</div>
`,
styles: [
`
.color-picker {
display: flex;
}
.color {
width: 20px;
height: 20px;
border: 1px solid #ccc;
}
.color.selected {
border: 2px solid #000;
}
`,
],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ColorPickerComponent),
multi: true,
},
],
})
export class ColorPickerComponent implements ControlValueAccessor {
@Input() colors: string[] = [];
selectedColor = '';
onChange: (value: string) => void = () => {};
onTouched: () => void = () => {};
writeValue(value: string): void {
this.selectedColor = value;
}
registerOnChange(fn: (value: string) => void): void {
this.onChange = fn;
}
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
selectColor(color: string) {
this.selectedColor = color;
this.onChange(color);
}
}
NG_VALUE_ACCESSOR
est une constante exportée par Angular qui définit un token de fournisseur de valeur. Elle est utilisée pour fournir une valeur à une directive ou un composant qui implémente l'interface ControlValueAccessor
.
Nous utilisons NG_VALUE_ACCESSOR
dans la définition de fournisseur du composant ColorPickerComponent
. Cela indique à Angular que ce composant implémente l'interface ControlValueAccessor
et qu'il peut être utilisé comme un contrôle de formulaire.
La propriété multi: true
de la définition de fournisseur indique à Angular qu'il doit créer une nouvelle instance du fournisseur pour chaque demande de fournisseur. Cela est utile lorsque vous avez plusieurs instances du même composant ou directive dans votre application et que vous voulez que chaque instance ait sa propre valeur. Si vous ne définissez pas multi: true
, Angular utilisera la même instance de fournisseur pour toutes les demandes.
Nous avons ensuite des méthodes à implémenter:
writeValue(value: any)
: Cette méthode est appelée par Angular lorsqu'il souhaite mettre à jour la valeur du composant avec une nouvelle valeur. Dans l'exemple, nous mettons simplement à jour la propriétéselectedColor
avec la valeur donnée.registerOnChange(fn: any)
: Cette méthode est appelée par Angular pour enregistrer une fonction à appeler lorsque la valeur du composant change. Dans l'exemple, nous enregistrons simplement la fonction donnée dans la propriétéonChange
.registerOnTouched(fn: any)
: Cette méthode est appelée par Angular pour enregistrer une fonction à appeler lorsque le composant est "touche" (par exemple lorsque l'utilisateur clique sur le composant). Dans l'exemple, nous enregistrons simplement la fonction donnée dans la propriétéonTouched
.
En utilisant ces méthodes, vous pouvez contrôler la valeur du composant et déclencher des événements lorsque la valeur change ou lorsque le composant est "touche". Cela vous permet de créer des composants de formulaire personnalisés qui s'intègrent parfaitement au système de formulaire d'Angular.
Comment utiliser dans le template HTML avec ngModel ?
Pour utiliser le composant ColorPickerComponent
dans le template HTML avec ngModel
, vous devez d'abord importer FormsModule
dans votre componsant Angular. Ensuite, vous pouvez utiliser ColorPickerComponent
dans votre template HTML comme n'importe quel autre composant de formulaire en utilisant la directive ngModel
:
ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-my-component',
standalone: true,
imports: [FormsModule],
template: `
<form>
<app-color-picker [(ngModel)]="selectedColor"></app-color-picker>
</form>
`,
})
export class MyComponent {
selectedColor: string = '';
}
Dans cet exemple, nous utilisons la syntaxe de liaison de données bidirectionnelle [(ngModel)]
pour lier la valeur du composant ColorPickerComponent
à la propriété selectedColor
de notre composant. Cela signifie que lorsque la valeur du composant change, la propriété selectedColor
sera mise à jour et inversement.
Qu'est ce c'est forwardRef ?
forwardRef
est une fonction Angular qui vous permet de référencer un composant ou une directive qui n'a pas encore été déclaré. Elle est souvent utilisée lorsque vous avez besoin de référencer un composant ou une directive qui se trouve dans un autre fichier ou dans le même fichier, mais qui est déclaré plus tard.
Voici un exemple de code qui utilise forwardRef
:
ts
import { forwardRef, Directive } from '@angular/core';
@Directive({
selector: '[appMyDirective]',
standalone: true,
providers: [
{
provide: 'someToken',
useExisting: forwardRef(() => MyDirective),
},
],
})
export class MyDirective {
// ...
}
Dans cet exemple, nous utilisons forwardRef
dans la propriété useExisting
de la définition de fournisseur de la directive. Cela nous permet de référencer la directive MyDirective
avant qu'elle ne soit déclarée.