J'ai une forme assez compliquée que je veux décomposer en composants individuels. Voici mon formulaire de base (seuls les champs d'exemple pris), j'utilise FormBuilder
:
"Cannot find the control with the name: 'test_type'"
Si j'essaye de connecter ceci à mes modèles, cela fonctionne parfaitement:
<meta-option-value [parent_form]="predictorQuestion"></meta-option-value>
Cela rend sans aucune erreur.
Si j'essaye de décomposer le meta_options.test_type
dans un composant de son posséder d'une manière comme:
component.ts
<mat-form-field fxFlex="25" [formGroup]="parent_form"> <mat-select formControlName="test_type"> <mat-option *ngFor="let vtype of vtypes" value="{{ vtype.value }}">{{ vtype.name }}</mat-option> </mat-select> </mat-form-field>
component.html p>
@Input() parent_form: FormGroup; public vtypes: Array<Object>; constructor(private fb: FormBuilder) { this.vtypes = [ { name: 'Timestamp', value: 'timestamp' }, { name: 'Over', value: 'over' } ]; }
et en utilisant ce composant dans ma forme parent principale comme
<form [formGroup]="predictorQuestion" fxLayout="column"> <mat-form-field fxFlex appearance="outline"> <mat-label>Question</mat-label> <input matInput formControlName="question"> </mat-form-field> <div fxLayoutAlign="space-between center"> <h3>Options</h3> <button (click)="addOption()" matTooltip="Add option" matTooltipPosition="right" mat-mini-fab type="button"> <mat-icon>add</mat-icon> </button> </div> <div formArrayName="options" fxLayout="column"> <div *ngFor="let answer of options.controls; let i = index" fxLayout="row" fxLayoutAlign="space-between stretch"> <mat-form-field appearance="outline" fxFlex> <mat-label>Option {{ i+1 }} </mat-label> <input fxFlex matInput [formControlName]="i"> </mat-form-field> <button mat-icon-button matTooltip="Remove this option" matTooltipPosition="right" (click)="removeOption(i)"> <mat-icon>close</mat-icon> </button> </div> </div> <div formGroupName="meta_options" fxLayoutAlign="space-between" fxLayoutGap="20px" fxLayout="column"> <mat-form-field fxFlex="25"> <mat-select formControlName="test_type"> <mat-option *ngFor="let vtype of vtypes" value="{{ vtype.value }}">{{ vtype.name }}</mat-option> </mat-select> </mat-form-field> </div> </form>
J'obtiens l'erreur suivante: strong >
ngOnInit() { this.predictorQuestion = this.fb.group({ question: ['', Validators.required], options: this.fb.array([ this.fb.control('', Validators.required), ]), meta_options: this.fb.group({ test_type: ['', Validators.required], }) }); get meta_options() { return this.predictorQuestion.get('meta_options') as FormGroup; } get options() { return this.predictorQuestion.get('options') as FormArray; }
Que me manque-t-il ici?
3 Réponses :
passez le "contrôle" itseft et utilisez [FormControl] dans vos enfants
<mat-form-field fxFlex="25" [formControl]="formControl"> ... </mat-form-field> //and add the Input @Input()formControl: FormControl;
Vos méta-options
<meta-option-value [formControl]="predictorQuestion.get('meta_options')"> </meta-option-value>
la même idée fonctionne si vous avez besoin de passer un FormGroup ou un Form Array
Vous transmettez le FormGroup (predictorQuestion)
complet à l'enfant. Il vous suffit de transmettre le predictorQuestion.get ('meta_types')
au parent_form
en tant que [parent_form] = "predictorQuestion.get ('meta_types')" < / code>.
Vous pouvez dire à votre composant enfant d'utiliser formControlName = "test_type"
en fonction du conteneur parent quel que soit le type de conteneur (FormGroupName, FormGroup our FormArray) en définissant viewProviders
:
meta-option-value.component.ts
<div formGroupName="meta_options"> /\ || will look at this group <meta-option-value></meta-option-value> </div>
parent.template.html
@Component({ selector: 'meta-option-value', template: ` <mat-form-field fxFlex="25"> <mat-select formControlName="test_type"> <mat-option ...>{{ vtype.name }}</mat-option> </mat-select> </mat-form-field> `, viewProviders: [{ provide: ControlContainer, useFactory: (container: ControlContainer) => container, deps: [[new SkipSelf(), ControlContainer]], }] }) export class MetaOptionValueComponent { ... }
Comme vous pouvez le voir, MetaOptionValueComponent ne contient que sa propre logique associée.
Voir aussi:
Bien sûr, une autre façon est de transmettre l'instance FormGroup ou FormControl et de l'utiliser directement comme suggéré dans d'autres réponses
Copie possible de Impossible de trouver le contrôle avec le nom: formControlName en angulaire 2 ou 4