在另一个指令中使用ngClass指令会引发控制台错误

时间:2015-05-13 17:18:30

标签: javascript angularjs angularjs-directive

我正在尝试在我的指令中使用ngClass,它正在工作,但我看到一个控制台错误:

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

以下是我的指令的简化版本,它重现了这个问题:

angular.module('myApp', [])
    .directive('myDirective', function () {
    return {
        restrict: 'E',
        scope: {
            myNgClass: '='
        },
        template: '<div ng-class="myNgClass">Hello World</div>'
    }
});

以下是我如何使用它:

<my-directive my-ng-class="{'green':true}"></my-directive>

here是jsFiddle的链接。

2 个答案:

答案 0 :(得分:2)

因此,首先,此错误特定于您正在使用的Angular版本(v1.2.1) - 它已在v1.2.5中修复(working demo与v1.2.5)。

其次,您实际上不应该使用双向绑定("="),因为您似乎不需要更改指令内的值。使用"="会不必要地创建2个观察者。

你绝对可以进行单向字符串绑定("@"),如下所示:

scope: {
  myNgClass: '@'
},
template: '<div ng-class="{{myNgClass}}">Hello World</div>'

但这将使用更有限。例如,您将无法将对象($scope.greenStyle = { green: true };)传递给您的指令:

<my-directive my-ng-class="greenStyle"></my-directive>

最好使用单向绑定表达式 - "&"。这样可以保留一只手表并绑定到一个对象 - 而不是字符串。 scope.myNgClass成为一个返回绑定表达式值的函数:

scope: {
  myNgClass: '&'
},
template: '<div ng-class="myNgClass()">Hello World</div>'

<强> Demo

答案 1 :(得分:1)

使用@代替=

myNgClass: '@'

当您使用= angular时,会添加$ watch以更改“myNgClass&#39;”。添加$ watch时,angular会将$$ hashKey添加到对象中,并尝试&#34;尝试&#34;将修改后的对象分配回其来源(以便源和目标具有相同的对象)。

问题是当$ digest比较它具有{'green':'true', $$hashKey: '123546246'}的对象与评估的表达式{'green':'true'}时,比较失败,因此$ watch监听器运行(注意:那部分只是我的理论。我不知道100%它添加了一个hashKey,但我知道它将对象视为不同的实例并且触发了监听器。 由于my-ng-class将始终发送回该对象的新实例,因此它将始终不同并始终触发监视侦听器。

如果你想继续使用=,你可以(但没有必要)。您只需在传入之前在其他地方定义初始对象。您可以使用ng-init来执行此操作,如下所示:

<my-directive ng-init="clazz={'green':'true'}" my-ng-class="clazz"></my-directive>