【问题标题】:How to validate a dynamic list of nested components form group?如何验证嵌套组件表单组的动态列表?
【发布时间】:2019-01-10 06:10:44
【问题描述】:

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

父项-表单-组件:

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

有没有更好的方法来实现这一点?我应该将表单组传递给每个孩子吗?

【问题讨论】:

    标签: angular typescript angular-reactive-forms


    【解决方案1】:

    在创建自定义表单组件时,建议实现NgValueAccessor

    这是how-to

    然后您可以使用您的自定义组件,例如 &lt;input&gt; 字段。

    <div [formGroup]="form">
        <app-item formControlName="user">
        </app-item>
    </div>
    

    用于验证的绑定也将起作用。

    &lt;span *ngIf="form?.get('user').invalid"&gt;Field Invalid&lt;/span&gt;

    ts:

    public form: FormGroup = new FormGroup({ 
      user: new FormControl(null, [Validators.required, customValidator]) 
    })
    

    【讨论】:

      猜你喜欢
      • 2018-10-10
      • 1970-01-01
      • 2018-03-06
      • 1970-01-01
      • 2022-06-15
      • 2017-08-13
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      相关资源
      最近更新 更多