我试图弄清楚为什么我无法覆盖通过隔离范围(@
)传递给 angularJS 指令的值。我尝试vm.index
用以下内容覆盖的值:
vm.index = parseInt(vm.index, 10)
但是,由于某种原因它不起作用。
如果我将其更改为:
vm.newIndex = parseInt(vm.index, 10)
有用。$scope
此外,在作品 上分配价值。
为什么第一种方法不起作用?
我创建了这个示例 plunker以供参考。
我试图弄清楚为什么我无法覆盖通过隔离范围(@
)传递给 angularJS 指令的值。我尝试vm.index
用以下内容覆盖的值:
vm.index = parseInt(vm.index, 10)
但是,由于某种原因它不起作用。
如果我将其更改为:
vm.newIndex = parseInt(vm.index, 10)
有用。$scope
此外,在作品 上分配价值。
为什么第一种方法不起作用?
我创建了这个示例 plunker以供参考。
正如您@
在此处使用的那样,它需要来自带有{{}}
插值指令的属性的值。似乎指令首先被加载,然后vm.index
值被评估。因此,在当前的摘要周期中没有发生变化。如果您希望反映这些内容,您需要使用 $timeout 以更安全的方式运行摘要循环。
$timeout(function(){
vm.index = parseInt(vm.index, 10)
})
上面的事情是确保将值转换为十进制值。添加将发生在指令 html 上<h2>Item {{ vm.index + 1 }}</h2>
根据@dsfq 和我的讨论,我们通过了角度$compile
API,发现它们是一种方法调用initializeDirectiveBindings
,只有当我们controllerAs
在具有隔离范围的指令中使用时才会调用。在这个函数中,有各种 binding 的 switch case@
和=
,&
所以当你使用@
这意味着调用 switch case 代码之后的一种绑定方式。
代码
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 回答之所以有效,是因为他使用=
了两种方式绑定,即代码不会让观察者直接从隔离范围中获取值,这里是代码。因此,如果没有摘要周期,该值就会更新。
index
显然它与作用域值的单向绑定有关。因此 Angular 不会更新scope.index
(或this.index
在 的情况下bindToController: true
),因为范围配置为
scope: {
index: '@'
},
如果将其更改为双向绑定,例如:
scope: {
index: '='
},
它将起作用:
<some-directive index="$index"></some-directive>
演示: http ://plnkr.co/edit/kq16cpk7gyw8IE7HiaQL?p=preview
升级版。@pankajparkar 提出了一个很好的观点,即在下一个摘要中更新值解决了这个问题。这种解决问题的方法比我在这个答案中所做的更接近。