【问题标题】:Method bound to checked attribute of angular mat-checkbox is triggered multiple times绑定到角度 mat-checkbox 的选中属性的方法被多次触发
【发布时间】:2018-04-04 10:48:39
【问题描述】:

我有一个嵌套的 JSON 数组,我通过它迭代来显示数据。每个对象都呈现为一个复选框,如果与名为“checked”的嵌套选项关联的值为 true,则选中复选框。如果该字段未选中,则“选中”选项设置为 false。 下面是带有一个对象的 HTML 代码和示例 JSON:

<ng-container *ngFor="let dm of data; let lst = last; let midx = index;">
  <mat-expansion-panel class="mar-bot-1">
    <mat-expansion-panel-header>
      <mat-panel-title>
        {{dm.name}} &nbsp;&nbsp;
      </mat-panel-title>
    </mat-expansion-panel-header>
    <section>
      <div *ngFor="let fd of dm.fields; let lst = last; let fst = first; let fidx = index;">
        <div class="row pad-left-1">
          <div class="col-md-12 col-xs-12">
                <mat-checkbox class="example-margin" color="primary" [checked]="checkSelected(midx, fidx)" (change)="onFieldChange(midx, fidx, $event)"
                [disabled]="fd.field.required" disableRipple>
                {{fd.field.fieldname}}
                <span *ngIf="fd.field.required" matTooltip="This field is required" style="color:#dc3545;">*</span>
                </mat-checkbox> &nbsp;
            </div>
        </div>
      </div>
    </section>
  </mat-expansion-panel>
</ng-container>

JSON:

data : [
    {   
        name: 'ABC',
        description: ''
        fields: [
            {
                field: {
                    fieldname: 'field1'
                    required: true
                },
                options: [
                    { field: {
                        fieldname: 'checked',
                        fieldtype: boolean,
                        fieldvalue: true
                      }
                    },
                    { field: {
                        fieldname: 'someoption'
                        fieldtype: string,
                        fieldvalue: 'maybestring'
                      }
                    }
                ]
            },
            {
                field: {
                    fieldname: 'field2'
                    required: false
                },
                options: [
                    { field: {
                        fieldname: 'checked',
                        fieldtype: boolean,
                        fieldvalue: false
                      }
                    },
                    { field: {
                        fieldname: 'someoption2'
                        fieldtype: string,
                        fieldvalue: 'maybestring'
                      }
                    }
                ]
            }
        ]
    }
]

当页面加载时,默认情况下通过将复选框绑定到方法checkSelected() 并在更改时调用 onFieldChange() 来勾选复选框。

checkSelected(midx, fidx) {
    //iterate over data and look for fieldvalue of checked option and return the value
}

onFieldChange(midx, fidx, $event) {
    //Iterate over data and set value as per the event to checked option
}

但问题是checkSelected() 在页面加载/打开或关闭扩展面板/选中复选框时调用onFieldChange() 时多次调用。

我确定没有对 checkSelected() 进行隐藏调用,但不知何故,它被多次调用(针对整个对象 - 遍历每个字段)导致expressionChangedAfterItHasBeenCheckedError我尝试设置一些标志(其他逻辑需要)。

如果有人可以指导我理解为什么绑定到属性的函数会被多次触发以及如何修复它!非常感谢任何帮助

【问题讨论】:

  • 这是预期的行为。每当检测到更改并呈现模板时,将调用该方法以确定返回值是什么。也许您应该寻求有关如何不让expressionChangedAfterItHasBeenCheckedError 发生的帮助。不过,您必须发布有关您的代码的更多详细信息以获得帮助。
  • 谢谢@DanielWSrimpel,非常感谢。了解如何克服多次调用会很有帮助,因为根据我的说法,我的代码完成了非常简单的任务。一旦到位,我应该能够修复expressionChangedAfterItHasBeenCheckedError。请让我知道是否有任何我可以关注的链接

标签: angular checkbox angular5 angular-material2


【解决方案1】:

不要绑定[checked](change),而是使用[(ngModel)] - 类似于[(ngModel)]="fd.options[0].field.fieldvalue"

【讨论】:

  • 问题在于 - 更多字段可能会添加到选项数组中,并且可能会根据项目需要重新排序后端中的对象。所以我不能用 ngModel 附加硬编码索引
  • 那么这真的取决于你如何实现checkSelectedonFieldChange。它没有理由不能工作,但您没有显示这些功能的代码。 Here is a stackblitz using your code with my own implementations of the checked and change functions 工作正常。
  • 非常感谢,感谢您的耐心等待!您的方法与我的方法非常相似,但是如果您检查代码,则在切换扩展面板或选中任何复选框时会多次调用 checkSelected。请检查 console.log() 消息,这正是我的问题。
  • 我认为这不是问题 - 那是 Angular :) 我认为无法控制或预测 Angular 何时或多久轮询更改。如果这是您面临的唯一“问题”,我建议忽略它。如果您遇到真正的性能问题 - 这可能是由于您实施检查的方式,而不是检查发生的次数比您打开和关闭扩展面板时应该发生的次数多几倍。但是,在 GitHub 上查看 Angular 的相关问题可能仍然值得。
猜你喜欢
  • 1970-01-01
  • 2021-03-24
  • 2021-08-15
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
  • 2020-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多