【问题标题】:Validation not Triggered When Custom FormControl Is Added to FormArray将自定义 FormControl 添加到 FormArray 时未触发验证
【发布时间】:2020-05-29 12:26:05
【问题描述】:

我有一个表单组,其中包含一组自定义表单控件(自定义表单控件也有验证)。每当我将新的表单控件推送到数组时,完整表单的验证都不会正常运行。

似乎当一个新的表单控件被推送时,首先运行父表单控件的验证,然后只运行子表单控件的验证。有没有人知道为什么?

请参考https://stackblitz.com/edit/angular-fh6vzw?embed=1&file=src/app/app.component.ts的stackblitz链接

【问题讨论】:

  • 你的 stackblitz 不工作
  • 你应该检查你的stackblitz,模板comic-book.component.html会加载导致应用程序中断的app-route...
  • 固定堆栈闪电战 :)

标签: angular angular-reactive-forms angular-validation reactive-forms


【解决方案1】:

你需要给 Angular 一个呼吸,就在你的 onAddHero 函数中,添加一个 setTimeout(()=>heroesArray.updateValueAndValidity()

onAddHero() {
    const heroesArray = this.formGroup.get('heroes') as FormArray;
    heroesArray.push(new FormControl({
      name: '',
      wealth: ''
    }));
    //this lines
    setTimeout(()=>{
        heroesArray.updateValueAndValidity()
    })
    console.log('hero added');
  }

顺便说一句,我认为这是一种“奇怪”的做事方式,对我来说更简单的是使用 @Input@Ouput 创建组件并从 app.component 管理表单

这就是我们的 app.component

<form [formGroup]="newForm" (submit)="onSubmit()">
    <div class="form-group">
        <label>Collection name<input formControlName="collectionName" class="form-control" /></label>
    </div>
    <app-comic-book [form]="newForm.get('comicBook')" (addHero)="addHero()"></app-comic-book>
    <button type="submit" [disabled]="!newForm.valid" class="btn btn-primary">Submit</button>
</form>
  newForm: FormGroup = this.fb.group({
    collectionName: 'classics 1',
    comicBook: this.fb.group({
      name: 'volume 1',
      heroes: this.fb.array([
        this.createHeroe({
          name: 'Superman',
          wealth: 'Piss poor'
        }),
        this.createHeroe({
          name: 'Batman',
          wealth: 'Crazy rich'
        })
      ])
    })
  });

  constructor(private fb: FormBuilder) { }

  createHeroe(data)
  {
    data=data || {name:'',wealth:''}
    return this.fb.group({
      name:[data.name,Validators.required],
      wealth:[data.wealth,Validators.required]
    })
  }
  addHero()
  {
    const heroes=this.newForm.get('comicBook.heroes') as FormArray;
    heroes.push(this.createHeroe(null))
  }
  onSubmit() {
    console.log(this.newForm);
  }

我们的漫画书组件

<div [formGroup]="formGroup">
    <div class="form-group">
        <label>Comicbook name<input formControlName="name" class="form-control" /></label>
    </div>
    <div formArrayName="heroes">
        <div *ngFor="let hero of formGroup.get('heroes').controls; let i = index">
            <app-hero [form]="hero"></app-hero>
        </div>
    </div>
  <button (click)="onAddHero()" class="btn btn-primary">Add Hero</button>
</div>

export class ComicBookComponent {
  @Input('form')formGroup
  @Output()addHero = new EventEmitter<any>();
  onAddHero()
  {
    this.addHero.emit()
  }
}

还有我们的英雄组件

<div [formGroup]="formGroup">
    <div class="form-group">
        <label>Hero name<input formControlName="name" class="form-control" /></label>
    </div>

    <div class="form-group">
        <label>Hero wealth<input formControlName="wealth" class="form-control" /></label>
    </div>
</div>

export class HeroComponent  {
  @Input('form')formGroup
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多