简体   繁体   English

在 Angular Reactive Form 中禁用基于多个空 formControlNames 的按钮

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

StackBlitz example StackBlitz 示例

I have a reactive form with a dynamic form array.我有一个带有动态表单数组的反应式表单。 There is a button to add new objects to the form.有一个按钮可以向表单添加新对象。 However, I only want this button to be "enabled" when the current object in the array has been populated/or is already populated.但是,我只希望在数组中的当前对象已填充/或已填充时“启用”此按钮。

 <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>

I need to add the attribute of disabled based on 3 fields to look to see if they are empty.我需要根据 3 个字段添加 disabled 属性以查看它们是否为空。 I tried this with one field to start with:我从一个领域开始尝试这个:

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

I thought the above would look at the description fields and see if it has value.我认为上面会查看描述字段,看看它是否有价值。

Any alternative methods welcome.欢迎任何替代方法。 I think the issue is that it needs to look at an array item.我认为问题在于它需要查看一个数组项。

StackBlitz example StackBlitz 示例

Your forked Stackblitz here .在这里分叉 Stackblitz。

Check the values in the last array item and disable the button based on the value.检查最后一个数组项中的值并根据该值禁用按钮。

Place the button inside looped div for getting the access of i (index)将按钮放置在循环 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>

I would use an observable, mainly because I like to handle all logic in template, also this is more reusable in my opinion instead of typing out all controls in template.我会使用 observable,主要是因为我喜欢处理模板中的所有逻辑,而且在我看来这更可重用,而不是在模板中输入所有控件。 What if you want to do a more complicated check for disabling, or what if your form control names change?如果您想对禁用进行更复杂的检查,或者如果您的表单控件名称发生更改,该怎么办? This is easier to handle in my opinion.在我看来,这更容易处理。 But yeah, it's an opinion, but thought to throw this out there :)但是,是的,这是一个意见,但想把它扔出去:)

So listen to the valuechanges of the formarray, at this point, only address the last item in the array and check that all properties of this object has values:所以监听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] === "")),
  )

Then in template use async pipe that unsubscribes for you :)然后在模板中使用为您取消订阅的async管道:)

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

I used Object.keys above as Stackblitz didn't like me using Object.values, so Object.values is also a valid approach!我在上面使用了 Object.keys,因为 Stackblitz 不喜欢我使用 Object.values,所以 Object.values 也是一种有效的方法!

DEMO 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM