我创建了一个简单的嵌套表单,通过子组件实现而不是将所有内容都放在一个组件中。我已经实现了一个非常基本的ControlValueAccessor,以使其能够以这种方式工作,但是我注意到验证不会在父组件中进行捕获。这意味着即使表单无效,也可以提交错误的表单。
如何将子表单的验证传播到父表单中?
以下是代码。
父级HTML
如何将子表单的验证传播到父表单中?
以下是代码。
父级HTML
<form [formGroup]="parentForm" (ngSubmit)="submitData()">
<h3>Parent</h3>
<br>
<ng-container formArrayName="children">
<ng-container *ngFor="let c of children?.controls; index as j">
<app-child [formControlName]="j"></app-child>
</ng-container>
</ng-container>
<button mat-raised-button type="button" (click)="addChild()">Add Activity</button>
<button mat-raised-button type="submit" color="warn" [disabled]="!parentForm.valid">Submit</button>
</form>
<pre>
{{parentForm.valid}} // this is always true because its not getting validator state from children
</pre>
<pre>
{{parentForm.value | json}}
</pre>
父级 TS
export class ParentComponent implements OnInit {
parentForm: FormGroup;
constructor(private fb: FormBuilder) {
}
ngOnInit(): void {
this.createForm();
}
private createForm() {
this.parentForm = this.fb.group({
children: this.fb.array([])
});
}
get children(): FormArray {
return this.parentForm.get("children") as FormArray;
}
addChild() {
const tempChild = new FormControl({
description: null
});
this.children.push(tempChild);
}
submitData() {
console.info(JSON.stringify(this.parentForm.value));
}
}
子HTML
<form [formGroup]="newChildForm">
<tr>
<td>
<mat-form-field>
<mat-label>Description</mat-label>
<input type="text" matInput formControlName="description" required>
</mat-form-field>
</td>
</tr>
</form>
子类型脚本
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ChildComponent),
multi: true
}
]
})
export class ChildComponent implements ControlValueAccessor, OnInit {
newChildForm: FormGroup;
constructor(private fb: FormBuilder) {
this.createForm();
}
private createForm() {
this.newChildForm = this.fb.group({
description: [null, Validators.required],
});
}
onTouched: () => void = () => { };
writeValue(value: any) {
if (value) {
this.newChildForm.setValue(value, { emitEvent: true });
}
}
registerOnChange(fn: (v: any) => void) {
this.newChildForm.valueChanges.subscribe((val) => {
fn(val);
});
}
setDisabledState(disabled: boolean) {
disabled ? this.newChildForm.disable() : this.newChildForm.enable();
}
registerOnTouched(fn: () => void) {
this.onTouched = fn;
}
ngOnInit(): void { }
}
编辑2:嵌套方法
angular editor
上分享你的 Angular 代码吗? - Suneel Kumar