【问题标题】:angular infinite digest loop from ng-model using getterSetter使用 getterSetter 的 ng-model 的角度无限摘要循环
【发布时间】:2015-10-22 18:16:17
【问题描述】:

这里是html:

<select style="width: 100%;" ng-model="vm.orgType" ng-model-options="{getterSetter: true}" ng-options="orgType as orgType.ORGANIZATION_TYPE for orgType in vm.orgTypes">
                                </select>

这里是getter/setter函数:

function orgType(selectedType) {
            if (arguments.length == 0)
                return orgType.selectedOrgType || { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null };

            orgType.selectedOrgType = selectedType;
            if (selectedType.ORGANIZATION_TYPE_ID) {
                if (vm.registrant.StakeholderOrgs[0])
                    vm.registrant.StakeholderOrgs[0] = selectedType.ORGANIZATION_TYPE_ID;
                else
                    vm.registrant.StakeholderOrgs.push(selectedType.ORGANIZATION_TYPE_ID);
            }
            else
                vm.registrant.StakeholderOrgs.splice(0);
        }

下面一行:

return orgType.selectedOrgType || { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null };

抛出无限摘要循环错误。

让我解释一下我想在这里做什么。如果进行了选择,我需要将 id 推送到列表中。我意识到我可以在某个变量 selectedOrgType 上做一个 ng-model,然后把我的逻辑放在一个 ng-change 中。但是,我正在尝试制作一个不会创建任何不必要的模型变量的下拉菜单。相反,我希望将逻辑放在 getter/setter 中,这对我来说似乎更合适。 vm.orgTypes 之一是 { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null },我希望这将是我的默认值,而不是我得到这个摘要错误,不明白它来自哪里。

【问题讨论】:

  • watch 在这种情况下检查等于引用,如果您返回{ ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null },则每个检查都返回 new 对象。如果您在集合中有相同的对象 - 只需像 return orgType.selectedOrgType || vm.orgTypes[0] 一样使用它。或者只是保存在变量中:var defVal = { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null } 并使用 return orgType.selectedOrgType || defVal
  • @Grundy 想要添加答案?

标签: javascript angularjs


【解决方案1】:

当您添加 ng-model 属性时,角度添加内部监视,检查每个摘要循环的值,如果值更改 - 再次运行摘要。

在您的情况下,您返回对象文字。在 javascript 中,当你比较两个文字时,即使结构相同 - 你会得到 false

({a:1} == {a:1}) // false

因为这确实是两个不同的对象。

因此,当您在 getter 中返回对象字面量时,watch 用之前的值检查它,并且,正如我上面所说,如果您返回字面量 - 获取 false

所以你得到了无限摘要的错误。

为了解决你只需要返回相同的对象。

如果你在数组中有这个对象,比如

vm.orgTypes=[
    { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null }
];

所以你只需要直接使用它:

 return orgType.selectedOrgType || orgTypes[0];

另一种方式:只需将默认值保存到变量并使用它

var defaultSelect = { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null };

....

function orgType(selectedType) {
    if (arguments.length == 0)
        return orgType.selectedOrgType || defaultSelect;

在这种情况下,您将在默认情况下返回相同的元素,因此请避免无限消化战利品。

【讨论】:

  • 我正在尝试规范化输入。 input 可以是input[type=text],也可以是&lt;select&gt;。我总是返回一个字面量的对象——我需要。你将如何解决这个问题?你的回答不是真的解决方案——你只是说不要那样做
  • @Cody,可能你在之后看不到代码,你只需要返回相同的对象。无论如何,你可以问你自己的问题,因为问题可能在其他地方跨度>
  • 我看到了 return same object 行——它就像一个魅力,如果你可以返回同一个对象。我的情况,它甚至可能不是一个选择。感谢您的输入。
  • @Cody,没有您的代码,我无法建议如何将我的答案应用于您的问题:)
猜你喜欢
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
相关资源
最近更新 更多