我有一个处理输入控件数组的子组件。我希望对子组件进行formcontrol。
我正在传递json对象的数组,这是将父表单绑定到子组件的正确方法,其中FormArray具有2个表单控件,首先需要使用Validator。
这是初始代码
<h1>Child</h1>
<div formArrayName="names">
<div *ngFor="let c of names.control">
<input formControlName="firstName">
<input formControlName="lastName">
</div>
</div>
意图是将父表单与子组件中的输入控件数组绑定。如果子组件中的一个输入控件没有必填字段,则表单也将变为无效。
答案 0 :(得分:1)
您必须使用formArrayName
指令和*ngFor
,如下所示:
<form [formGroup]="form" (ngSubmit)="sayHello()">
<input formControlName="name"><br>
<input formControlName="email"><br>
<div formArrayName="username">
<div *ngFor="let user of username.controls; let i=index">
<my-child formControlName="i"></my-child>
</div>
</div>
<button type="submit">Register</button>
</form>
使用FormBuilder
时,您还必须使用FormArray
。
form = new FormGroup({
name: new FormControl('My Name'),
username: new FormArray([
new FormControl("value"),// ControlValueAccesor is applied only to one control, not two. So you cannot use javascript object like you are using below this line.
{firstName:"Anna", lastName:"Smith"},
{firstName:"Peter", lastName:"Jones"}
])
});
有关详细信息,请see this doc.
案例2:传递FormGroup:
form = new FormGroup({
name: new FormControl('My Name'),
username: new FormArray([
new FormGroup({
firstName: new FormControl('Anna'),
lastName: new FormControl('Smith')
}),
new FormGroup({
firstName: new FormControl('Peper'),
lastName: new FormControl('Jones')
}),
])
})
如果您要将FormGroup作为ngModel参数传递,则不能!
答案 1 :(得分:0)
我喜欢解决旧帖子:)
关键是您的自定义窗体组件在FormArray内部,然后使用“ writeValue”创建formArray,请参见stackblitz
@Component({
selector: "my-child",
template: `
<h1>Child</h1>
<div *ngFor="let group of formArray.controls" [formGroup]="group">
<input formControlName="firstName" (blur)="_onTouched()" />
<input formControlName="lastName" (blur)="_onTouched()"/>
</div>
`,
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: Child, multi: true },
{ provide: NG_VALIDATORS, useExisting: Child, multi: true }
]
})
export class Child implements ControlValueAccessor {
formArray: FormArray;
_onChange;
_onTouched;
writeValue(value: any) {
this.formArray = new FormArray(
value.map(x => {
return new FormGroup({
firstName: new FormControl(x.firstName, Validators.required),
lastName: new FormControl(x.firstName, Validators.required)
});
})
);
this.formArray.valueChanges.subscribe(res => {
this._onChange(res);
});
}
registerOnChange(fn: (value: any) => void) {
this._onChange = fn;
}
registerOnTouched(fn:(value: any) => void) {
this._onTouched=fn;
}
validate({ value }: FormControl) {
return !this.formArray || this.formArray.valid
? null
: { error: "Some fields are not fullfilled" };
}
}