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 { 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 !