为什么我不能覆盖这样的变量的值?

时间:2015-06-23 20:33:14

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-controlleras

我试图找出为什么我无法通过隔离范围(@)覆盖传递给angularJS指令的值。我尝试使用以下内容覆盖vm.index的值:

vm.index = parseInt(vm.index, 10)

但是,由于某种原因,它不起作用。

如果我将其更改为:

vm.newIndex = parseInt(vm.index, 10)

有效。此外,在$scope上分配值也可以。

为什么第一种方法不起作用?

我已创建此example plunker以供参考。

2 个答案:

答案 0 :(得分:7)

正如您在@使用{{}}需要来自具有vm.index插值指令的属性的值一样。似乎指令正在加载第一个&然后评估$timeout(function(){ vm.index = parseInt(vm.index, 10) }) 值。因此,当前的摘要周期中没有发生变化。如果你想要反映这些,你需要使用$ timeout以更安全的方式运行摘要周期。

<h2>Item {{ vm.index + 1 }}</h2>

以上是确保将值转换为十进制值。添加将在指令html controllerAs

上进行

Working Demo

背后的可能原因

根据@dsfq&amp;我的讨论我们通过了角度$compile API,&amp;发现它们是一个方法调用initializeDirectiveBindings只有当我们在带有隔离范围的指令中使用@时才会调用它。在此函数中,存在各种绑定=&@的切换案例,因此当您使用case '@': if (!optional && !hasOwnProperty.call(attrs, attrName)) { destination[scopeName] = attrs[attrName] = void 0; } attrs.$observe(attrName, function(value) { if (isString(value)) { destination[scopeName] = value; } }); attrs.$$observers[attrName].$$scope = scope; if (isString(attrs[attrName])) { // If the attribute has been provided then we trigger an interpolation to ensure // the value is there for use in the link fn destination[scopeName] = $interpolate(attrs[attrName])(scope); } break; 时,这意味着调用跟随切换案例代码的单向绑定

<强>代码

attrs.$observe

在上面的代码中,您可以清楚地看到他们放置了{{index}}这是一种观察者,通常在值与插值时使用,就像在我们的情况下它是相同的$observe,这意味着在摘要周期运行时评估此$timeout,这就是为什么在将index值设为decimal时需要放置=

@dsfq回答的原因是因为他使用{{1}}提供了双向绑定,而代码并没有让观察者直接从隔离范围here is the code获取值。因此,如果没有摘要周期,则值会更新。

答案 1 :(得分:6)

显然它与范围index值的单向绑定有关。因此,在scope.index的情况下,Angular不会更新this.index(或bindToController: true因为范围已配置为

scope: {
    index: '@'
},

如果您将其更改为双向绑定,例如:

scope: {
    index: '='
},

它会起作用:

<some-directive index="$index"></some-directive>

演示: http://plnkr.co/edit/kq16cpk7gyw8IE7HiaQL?p=preview

<强> UPD 即可。 @pankajparkar明确指出,在下一个摘要中更新值可以解决问题。这个问题的方法比我在这个答案中所做的更接近。

相关问题