我有一个组件,其中包含嵌套组件的动态列表。在每个嵌套组件中,都有一个表单组来对其进行验证。这是父组件的代码:
父项形式组件:
export class ItemFromComponent implements OnInit {
@ViewChildren('item') items: QueryList<ItemComponent>;
itemList: Item[] = [];
constructor(private _formBuilder: FormBuilder) {
this.addItem();
}
itemListValidator(items: QueryList<ItemComponent>): ValidatorFn {
return (control: AbstractControl): { [key: string]: boolean } | null => {
if (items) {
for (let i = 0; i < items.length; i++) {
if (items[i].itemFormGroup.invalid) {
return {'isNotValid': true};
}
}
return null;
} else {
return null;
}
};
}
addItem(): void {
const item = new Item();
this.itemList.push(item);
}
ngOnInit() {
this.itemsFormGroup = this._formBuilder.group({
itemListFormControl: ['', this.itemListValidator(this.items)]
});
}
父模板:
<app-ribbon text="New product items"></app-ribbon>
<form class="form-wrapper" [formGroup]="itemsFormGroup">
<button mat-fab class="add-item-button" color="primary" matTooltip="Add one more item" (click)="addItem()">
<mat-icon aria-label="Add one empty item to the list">add</mat-icon>
</button>
<mat-accordion class="example-headers-align">
<div *ngFor="let item of itemList; let i = index">
<app-item #item
(deleteItem)="removeItem($event)"
(cloneItem)="cloneItem($event)"
[item]="item"
[index]="i"
[expanded]="i === 0 ? true : false">
</app-item>
</div>
</mat-accordion>
</form>
这里最困难的部分是项目的数量是动态的,因此我尝试使用自定义验证器函数来验证这些组件,该函数将参数作为子组件的列表。如果其中之一无效,则应为用户返回错误。
由于子组件列表最初为空,因此我的自定义验证器始终返回null,因为该列表未定义。此外,我的自定义验证程序仅在init上进行验证。每当用户在子组件中添加新输入时,我都需要它来验证列表。也许是孩子的事件发出者?
是否有更好的方法来实现这一目标?我应该将表格组传递给每个孩子吗?
答案 0 :(得分:0)
在创建自定义表单组件时,建议实现NgValueAccessor。
这里是how-to。
然后,您可以像<input>
字段那样使用自定义组件。
<div [formGroup]="form">
<app-item formControlName="user">
</app-item>
</div>
验证绑定也将起作用。
<span *ngIf="form?.get('user').invalid">Field Invalid</span>
ts:
public form: FormGroup = new FormGroup({
user: new FormControl(null, [Validators.required, customValidator])
})