Angular Signal Forms

Un retour sur la nouvelle fonctionnalité Angular Signal Forms depuis sa présentation à l'évènement Angular Connect 2025.
par Alain BOUDARD - Frontend tech enthousiast / road / downhill rider / kitesurf / run : @angular @QwikDev @ionicframework - member of @QwikDevParis
| minutes de lecture

RIP CVA, le retour de la pierre tombale … ou pas ?

De retour d'Angular Connect 2025 à Londres, je dois dire que la conférence était géniale ! Nous avons eu un contenu de qualité et c'était l'occasion de revoir des amis et des personnes que l'on croise seulement de temps en temps dans la communauté Angular.

De nombreuses discussions ont porté sur l'IA, évidemment, et sur la façon dont l'équipe se prépare aux deux prochains défis liés à ce domaine :

  • Comment améliorer les outils basés sur l'IA pour une expérience utilisateur optimale ?
  • Comment créer des API en Angular permettant de développer des applications compatibles avec l'IA ?

À ce sujet, vous pouvez consulter et participer à cette RFC : https://github.com/angular/angular/discussions/63766

Signal Forms

L'un des principaux sujets abordés était bien sûr Angular Signal Forms. 
Je n'entrerai pas dans les détails de cette fonctionnalité encore en phase expérimentale.
À l'heure où j'écris ces lignes, Angular devrait être en version 21.0.0-next-4, et il est évidemment trop tôt pour tirer des conclusions.

Par ailleurs, des personnes très compétentes ont écrit des articles et réalisé des vidéos à ce sujet : Angular Signal-Based Forms (Experimental) — First Look!

Mais, comme je continue à donner des formations sur Angular, je peux affirmer sans risque de me tromper que l'une des pires API d'Angular, et donc l'une des moins appréciées, est le fameux Control Value Accessor.

https://angular.dev/api/forms/ControlValueAccessor

Cette API permet aux développeurs de créer des éléments de formulaire personnalisés, élégants et polyvalents, de toute nature et avec toute interface. C'est indispensable dans un framework doté d'un module de gestion de formulaires avec des API bien définies, contrairement à Vue.js par exemple.

Lors de la conférence, nous avons assisté à une présentation accompagnée d'une démonstration de Signal Forms. Une présentation assez classique, mais ce que j'attendais, c'était la technique pour créer un champ de formulaire personnalisé.

Le moment est arrivé et c'était quelque chose, j'ai posté un message sur X :

Malheureusement, j'avais complètement oublié comment faire ! 
Impossible de m'en souvenir une fois dans mon train pour Paris ! Je me suis retrouvé avec un Stackblitz Angular 21.0.0-next.2 et aucun champ de formulaire personnalisé.
Il était donc temps de mener quelques investigations. Le package Signal Forms est disponible ici : 

https://github.com/angular/angular/tree/main/packages/forms/signals

Je connais un peu le fonctionnement interne d'Angular, je me suis donc rendu dans le dossier tests et j'y ai trouvé une implémentation vraiment (vraiment) géniale : 

it('synchronizes with a custom value control', () => {

    @Component({
      selector: 'my-input',
      template: '<input #i [value]="value()" (input)="value.set(i.value)" />',
    })
    class CustomInput implements FormValueControl<string> {
      value = model('');
    }

    @Component({
      imports: [Control, CustomInput],
      template: `<my-input [control]="f" />`,
    })
    class TestCmp {
      f = form<string>(signal('test'));
    }

    const fix = act(() => TestBed.createComponent(TestCmp));
    const input = fix.nativeElement.firstChild.firstChild as HTMLInputElement;
    const cmp = fix.componentInstance as TestCmp;

    // Initial state
    expect(input.value).toBe('test');

    // Model -> View
    act(() => cmp.f().value.set('testing'));
    expect(input.value).toBe('testing');

    // View -> Model
    act(() => {
      input.value = 'typing';
      input.dispatchEvent(new Event('input'));
    });
    expect(cmp.f().value()).toBe('typing');
  });

Vous avez vu ça ???

Bon, ça me suffit comme information, je me suis dirigé vers l'interface mentionnée FormValueControl<T> dans le dépôt.

La description est assez simple :

export  interface  FormValueControl < TValue > extends  FormUiControl { 
  /** 
   * La valeur est la seule propriété obligatoire dans ce contrat. Un composant qui souhaite s'intégrer 
   * à la directive `Control` via ce contrat, *doit* fournir un `model()` qui sera maintenu 
   * synchronisé avec la valeur du `Field` lié. 
  */ 
  readonly  value : ModelSignal < TValue >;

 

Voyons maintenant comment cela fonctionne dans mon StackBlitz :

https://stackblitz.com/edit/stackblitz-starters-cp9oh4lw?file=src%2Fcomp%2Fcustom%2Fcustom.ts

Voici donc le code du composant :

export class Custom implements FormValueControl<string> {
  value = model<string>('');
}

 

Je n'ai pas pu m'empêcher de jeter un coup d'œil à la directive `[control]` : 

https://github.com/angular/angular/blob/main/packages/forms/signals/src/api/control_directive.ts

Il est fait mention de l'infâme ControlValueAccessor dans les imports ! Quelle est cette sorcellerie ! 

S'agit-il d'un simple shell ou d'une surcouche du CVA ? 

Mais voici la révélation : qu'est-ce que c'est que cette directive ? On peut lire dans les commentaires du code :

 

* Binds a form `Field` to a UI control that edits it. A UI control can be one of several things:
 * 1. A native HTML input or textarea
 * 2. A signal forms custom control that implements `FormValueControl` or `FormCheckboxControl`
 * 3. A component that provides a ControlValueAccessor. This should only be used to backwards
 *    compatibility with reactive forms. Prefer options (1) and (2).

 

Le CVA est donc là pour assurer la rétrocompatibilité, et c'est effectivement l'un des points forts d'Angular.

Conclusion

Super, j'ai ma réponse ! Je n'étais même pas au courant quand j'ai envoyé mon message sur X, principalement parce que je ne suis pas de près les différents projets en cours sur le dépôt principal. Mais oui, c'est tellement plus simple que le CVA !
J'adore la direction que prend Angular.

 

Derniers mots : Je suis ravi d'avoir pu rencontrer autant de personnes formidables de la communauté Angular : Matthieu Riegler, Shai Reznik, Manfred Steyer, Gérôme Grignon, et quelques nouvelles personnes comme Mike Ryan, Andrés Gesteira et d'autres dont les noms m'échappent. Michael Hladky a organisé une excellente conférence ; même si elle n'a duré qu'une journée, j'ai passé un très bon moment. Et puis, courir à Hyde Park au milieu des écureuils le matin, c'est toujours un pur bonheur !

Search

language-lib

tools

Contenus associés

GraphQL une Nième Base de Données ? Ou pas …

GraphQL est un langage de requête et de manipulation de données développé par Facebook, offrant une approche flexible pour interagir avec les API. Dans cet article, nous explorerons ses cas d'utilisation, ses avantages et ses inconvénients.

Apache Kafka, un nouvel usage à venir ? KIP-932 Queues for Kafka

Kafka est une plateforme de data streaming offrant réplication, partitionnement et ordre des messages. Mal adapté au message queuing, la KIP-932 introduira des share groups pour plus de flexibilité et d’usages.

Podman : une alternative à Docker

Podman, alternative open source à Docker, offre une CLI similaire, compatible avec Docker Compose, rootless et sans démon. Facile à installer sous WSL2, il utilise les normes Open Container Initiative