反应形式正在验证列表中的所有迭代

时间:2020-06-22 11:15:46

标签: angular typescript

我正在* ngFor内使用反应形式来在我的应用程序中进行验证。但是,当我仅尝试验证一次迭代时,该表单将在所有迭代中都得到验证。

我尝试使用模板驱动的表单,并且运行良好。以下是模板驱动表单的工作代码

<div class="form-group col">
  <label>Flower License</label>
  <input type="text" name="fLicense" class="form-control" [(ngModel)]="f.fLicense" #fLicense="ngModel" [ngClass]="{ 'is-invalid': statusForm.submitted && fLicense.invalid }" required>
  <div *ngIf="statusForm.submitted && fLicense.invalid" class="invalid-feedback">
    <div *ngIf="fLicense.errors.required">flower License is required</div>
  </div>
</div>

对于反应式方法,下面是我的代码 HTML

<div *ngFor="let f of flowers">
  <div>{{f.type}} </div>
  <form [formGroup]="statusForm" (ngSubmit)="submitStatus()">
    <div class="form-group col-sm-4">
      <label>Flower License</label>
      <input class="form-control" type="text" formControlName="fLicense" [class.invalid]="!statusForm.controls['fLicense'].valid && statusForm.controls['fLicense'].touched ">
      <div *ngIf="!statusForm.controls['fLicense'].valid && (statusForm.controls['fLicense'].touched || isSubmitted)">
        <div class="invalid-feedback" style="display: block;">Please enter flower License Number</div>
      </div>
  </form>
  </div>
</div>

ts

ngOnInit() {
  this.statusForm = this.formBuilder.group({
    fLicense: ['', Validators.required],
  });
}

submitStatus(f) {
  this.isSubmitted = true;
  // stop here if form is invalid
  if (this.statusForm.invalid) {
    return;
  }
}

我尝试使用FormArray来执行此操作,但是无法在表单数组中包含formControl。抛出错误

  const newArray = new FormArray({
      this.statusForm = new FormGroup({
        hempLicense: new FormControl(['', Validators.required])
      })

    });

2 个答案:

答案 0 :(得分:1)

由于具有值数组,因此必须创建FormArray而不是FormControl。

 this.statusForm = this.formBuilder.group({
      fLicense: this.formBuilder.array(this.createFLicenseArray(this.flowers))
 });

 createFLicenseArray(flowers) {
     return flowers.map(flower =>
      this.formBuilder.control("", [Validators.required]));
 }

然后循环使用formArray控件显示单个许可

<form [formGroup]="statusForm">
    <div class="form-group col-sm-4" formArrayName="fLicense" *ngFor="let flow of fLicenseArray.controls;let i = index">
        <label>Flower License</label>
        <input class="form-control" type="text" [formControlName]="i">
        <div *ngIf="!fLicenseArray.at(i).valid && (fLicenseArray.at(i).touched)">
            <div class="invalid-feedback" style="display: block;">Please enter flower License Number</div>
        </div>
    </div>
</form>

Example

答案 1 :(得分:1)

这是一个可行的示例-https://codesandbox.io/s/reactive-form-is-validating-for-all-iterations-in-the-list-ioijo

我建议的解决方案是为表单创建另一个组件。

<div *ngFor="let f of flowers">
  <app-flower-form [data]="f"></app-flower-form>
</div>

花形组件看起来像这样-

export class FlowerFormComponent implements OnInit {
  @Input() data: FlowerInterface = null;

  public isSubmitted: boolean;
  public statusForm: FormGroup;

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.statusForm = this.formBuilder.group({
      fLicense: ["", Validators.required]
    });
  }

  submitStatus(f) {
    this.isSubmitted = true;

    if (this.statusForm.invalid) {
      return;
    }
  }
}

内部花形组件html

<form [formGroup]="statusForm" (ngSubmit)="submitStatus()">
  <div class="form-group col-sm-4">
    <h5>{{ data.type }}</h5>
    <label>Flower License</label>
    <input
      class="form-control"
      type="text"
      formControlName="fLicense"
      [class.invalid]="!statusForm.controls['fLicense'].valid && statusForm.controls['fLicense'].touched "
    />
    <div
      *ngIf="!statusForm.controls['fLicense'].valid && (statusForm.controls['fLicense'].touched || isSubmitted)"
    >
      <div class="invalid-feedback" style="display: block;">
        Please enter flower License Number
      </div>
    </div>
  </div>
</form>