如何验证嵌套组件表单组的动态列表?

时间:2018-08-02 12:51:59

标签: angular typescript angular-reactive-forms

我有一个组件,其中包含嵌套组件的动态列表。在每个嵌套组件中,都有一个表单组来对其进行验证。这是父组件的代码:

父项形式组件:

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上进行验证。每当用户在子组件中添加新输入时,我都需要它来验证列表。也许是孩子的事件发出者?

是否有更好的方法来实现这一目标?我应该将表格组传递给每个孩子吗?

1 个答案:

答案 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]) 
})