在 Angular 响应式表单中禁用基于多个空 formControlNames 的按钮

Disable a button based on multiple empty formControlNames in an Angular Reactive Form

StackBlitz example

我有一个带有动态表单数组的反应式表单。有一个按钮可以将新对象添加到表单中。但是,我只希望在数组中的当前对象 populated/or 已填充时“启用”此按钮。

 <div *ngIf="form">
  <form [formGroup]="form">
    <div formArrayName="justificationItems">
      <div *ngFor="let orgs of form.controls['justificationItems']?.controls;  let i = index"
        [formGroupName]="i">
        <input formControlName="name" placeholder="Item name">
        <input formControlName="description" placeholder="Item description">
        <input formControlName="code" placeholder="Item price">
        </div>
        <button [disabled]="!form.controls['justificationItems']?.controls.description" type="button" (click)="addItem()">Add Item</button>
      </div>
  </form>
</div>

我需要根据3个字段添加disabled属性,看看它们是否为空。我尝试从一个字段开始:

[disabled]="!form.controls['justificationItems']?.controls.description"

我以为上面会查看描述字段,看看它是否有价值。

欢迎任何替代方法。我认为问题在于它需要查看数组项。

StackBlitz example

你的分叉 Stackblitz here

检查最后一个数组项中的值,并根据该值禁用按钮。

将按钮放在循环内 div 以获取 i(索引)

的访问权限
<button
      *ngIf="i == form.value.justificationItems.length - 1"
      [disabled]="
        !form.value.justificationItems[i].name ||
        !form.value.justificationItems[i].description ||
        !form.value.justificationItems[i].code
      "
      type="button"
      (click)="addItem()"
    >  Add Item
        </button>

我会使用 observable,主要是因为我喜欢在模板中处理所有逻辑,而且我认为这比在模板中键入所有控件更可重用。如果您想对禁用进行更复杂的检查,或者如果您的表单控件名称更改怎么办?我认为这更容易处理。但是,是的,这是一个意见,但我想把它扔在那里 :)

所以监听formarray的valuechanges,此时,只寻址数组中的最后一项,检查这个对象的所有属性是否都有值:

  this.isDisabled$ = this.form.get('justificationItems').valueChanges.pipe(
    map(value => value[value.length-1]),
    map(val => Object.keys(val).some(x => val[x] === "")),
  )

然后在模板中使用 async 为您退订的管道 :)

<button [disabled]="isDisabled$ | async" type="button" (click)="addItem()">Add Item</button>

我在上面使用了 Object.keys,因为 Stackblitz 不喜欢我使用 Object.values,所以 Object.values 也是一个有效的方法!

DEMO