Encyclopédie des erreurs

NgModel dans un composant enfant ne peut pas atteindre le formulaire parent

Cet avertissement est émis lorsque ngModel (ou tout contrôle de template-driven form) est placé dans un composant enfant dont le composant parent héberge une directive de formulaire (NgForm ou FormGroupDirective), mais que le contrôle ne peut pas s'enregistrer auprès de ce formulaire.

La cause profonde est que NgModel injecte ControlContainer avec @Host(), ce qui empêche l'injector de franchir les frontières des composants. La directive de formulaire du template du composant parent est invisible pour NgModel dans le template de l'enfant.

Par conséquent, les contrôles de l'enfant se comportent silencieusement en standalone — ils ne participent ni à la valeur, ni à la validité, ni à l'état de soumission du formulaire parent.

Corriger l'avertissement

Option 1 : relier le ControlContainer avec viewProviders

Ajoutez viewProviders au composant enfant pour qu'il réexporte le formulaire parent dans sa propre vue. Utilisez la même classe que celle nommée par l'avertissement — NgForm pour les template-driven forms (<form>), ou FormGroupDirective pour les reactive forms ([formGroup]) :

// Parent uses a template-driven form: <form> ... <app-child> </form>
import {ControlContainer, NgForm} from '@angular/forms';
import {Component} from '@angular/core';

@Component({
  selector: 'app-child',
  template: `<input name="email" [(ngModel)]="email" />`,
  viewProviders: [{provide: ControlContainer, useExisting: NgForm}],
})
export class Child {
  email = '';
}
// Parent uses a reactive form: <div [formGroup]="myGroup"> ... <app-child> </div>
import {ControlContainer, FormGroupDirective} from '@angular/forms';
import {Component} from '@angular/core';

@Component({
  selector: 'app-child',
  template: `<input name="email" [(ngModel)]="email" />`,
  viewProviders: [{provide: ControlContainer, useExisting: FormGroupDirective}],
})
export class Child {
  email = '';
}

Le formulaire parent voit et valide alors normalement les contrôles de l'enfant.

Option 2 : marquer le contrôle comme standalone

Si les contrôles de l'enfant doivent réellement être indépendants du formulaire parent, désactivez explicitement l'enregistrement :

<input name="email" [(ngModel)]="email" [ngModelOptions]="{standalone: true}" />

Déboguer l'avertissement

Le message d'avertissement inclut le code d'erreur NG01354. Utilisez la pile d'appels pour localiser quel ngModel l'a déclenché. Vérifiez si le composant qui possède la balise <form> est le même composant que celui qui possède l'input ngModel — s'ils diffèrent, appliquez l'une des options ci-dessus.