【问题标题】:Angular 2 [disabled] only works on some controlsAngular 2 [禁用] 仅适用于某些控件
【发布时间】:2017-11-27 07:19:41
【问题描述】:

我有一个大表格,它是根据我从服务器提供的数据动态生成的。为了生成单选按钮,我使用以下 HTML:

<ng-container *ngSwitchCase="'RADIO'">
  <td *ngFor="let option of item.SelectOptions">
    <div class="input-group">
      <input type="radio"
        [(ngModel)]="item.PricingSelectIndex"
        name="{{ item.UIName }}RadioButton"
        id="{{ item.UIName }}{{ option.PricingSelectIndex }}"
        [value]="option.PricingSelectIndex"
        [disabled]="item.ReadonlyTF"
        (click)="saveField(item.UIName, 'SelectIndex', option.PricingSelectIndex)" />
      <label for="{{ item.UIName }}{{ option.PricingSelectIndex }}" style="margin-left: 5px;">
        {{ option.Label }}
        <i class="fa fa-question-circle" [tooltip]="item.TooltipText" placement="right" *ngIf="item.TooltipText"></i>
      </label>
    </div>
  </td>
</ng-container>

显然这是一个较大页面的一部分,它从数据中查看每个项目并根据项目的 ControlType 属性生成表单——这是单选按钮的 HTML。数据项包含一个名为 ReadonlyTF 的属性,它告诉我是否应该禁用控件(例如只读)。然后,该项目包含一个 SelectOptions 属性,该属性是一组较小的项目,每个项目都映射到集合中的一个单选按钮。 (例如,我遇到问题的控件有两个 SelectOptions,一个代表是,一个代表否。)因此,每个单选按钮都使用相同的 HTML 生成。

这是奇怪的事情。在有问题的控件中,生成的第一个单选按钮被禁用(这是我想要的),但第二个不是。

如果您仔细观察,您会发现 Yes 已禁用,但 No 没有!下面是这两个控件在 Chrome 的 Elements 选项卡中的呈现方式:

两者都包括ng-reflect-is-disabled="true",但实际上只有第一个被禁用。第二个按钮缺少ng-reflect-value。同样,这些都是使用完全相同的 HTML sn-p 呈现的。

我正在使用 Angular 2.4.6、Typescript 2.1.5、bootstrap 3.3.7 和 angular-cli 进行编译。组件中没有支持 TS 会影响这一点:我获取数据并将其弹出到一个属性中,然后由 HTML 模板拾取,仅此而已。我认为这可能是某种变更检测问题,但用changeDetectorRef.detectChanges() 强制它没有做任何事情。我对此感到困惑,但我不能有一个活动的单选按钮坐在那里供任何人点击!

谢谢!

【问题讨论】:

  • 你能设置一个它在 plnkr 中行为不端的例子吗
  • 具有讽刺意味的是,通过掩盖 html 中的名称,您阻止了人们找到答案。我遇到了同样的行为并且能够弄清楚。
  • 这应该发生,请查看fool stackblitz,检查您的代码

标签: angular angular2-template


【解决方案1】:

我知道这是一个糟糕的解决方案,但它会有所帮助:

<input *ngIf="shouldBeDisabled" name="foo" disabled>
<input *ngIf="!shouldBeDisabled" name="foo">

【讨论】:

  • 是的,这是一个糟糕的解决方案,实际上它不是一个正确的答案(错误在其他地方)
【解决方案2】:

发生这种情况的原因是您有多个带有NgModel 指令和相同name 属性的输入元素。 NgModel 的内部逻辑根据disabled 输入的值在表单控件上切换disable()enable()。由于名称冲突,您只有一个表单控件,因此在更远的地方,只有第一个元素会被更新。

使名称属性独一无二,您的问题应该会消失。

如果您查看 ng_model.ts 的源代码,您可以了解此行为。

【讨论】:

  • 嗯,一年后我仍然遇到这个问题,谷歌搜索,找到了我自己的 StackOverflow 问题。您的解决方案一针见血,谢谢!我很好奇,这不会引起问题吗,因为同一组中的单选按钮应该共享相同的名称?
  • 同样的限制适用——共享名称的每个单选按钮都必须绑定到完全相同模型。每个收音机不能有不同的型号。当您认为模型只能具有一个收音机的值时,这是有道理的,因为一次只能选择一个。
  • @DanielGimenez,收音机应该具有相同的 [(ngModel)] 和 name 属性。 fool stackblitz
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-06
  • 2020-10-24
  • 2018-11-09
  • 2012-10-30
  • 2020-10-21
  • 2019-04-11
相关资源
最近更新 更多