Rap*_*nah 7 javascript angularjs angularjs-directive angularjs-scope angularjs-controlleras
我试图找出为什么我无法通过isolate scope(@)覆盖传递给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)
})
Run Code Online (Sandbox Code Playgroud)
以上是确保将值转换为十进制值.添加将在指令html上发生<h2>Item {{ vm.index + 1 }}</h2>
根据@dsfq和我的讨论,我们通过了角度$compileAPI,发现它们是一个方法调用initializeDirectiveBindings,只有当我们controllerAs在带有隔离范围的指令中使用时才会调用它.在这个功能有开关的情况下的各种约束@,=并且&,这样你使用@,这意味着一个双向绑定下面的开关情况下的代码被调用.
码
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;
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,您可以清楚地看到它们放置的attrs.$observe是哪种观察器通常在值与插值时使用,就像在我们的情况下它是相同的{{index}},这意味着$observe在摘要循环运行时这会被评估,这就是你需要的原因把价值放在$timeout一边.indexdecimal
@dsfq回答的原因是因为他使用=提供了双向绑定,而代码并没有让观察者直接从隔离范围中获取值,这里是代码.因此,没有摘要周期,价值会得到更新.
显然它与范围index值的单向绑定有关.因此,Angular不会更新scope.index(或this.index在情况下bindToController: true),因为范围配置为
scope: {
index: '@'
},
Run Code Online (Sandbox Code Playgroud)
如果您将其更改为双向绑定,如:
scope: {
index: '='
},
Run Code Online (Sandbox Code Playgroud)
它会工作:
<some-directive index="$index"></some-directive>
Run Code Online (Sandbox Code Playgroud)
演示: http ://plnkr.co/edit/kq16cpk7gyw8IE7HiaQL?p = preview
UPD.@pankajparkar明确指出,在下一个摘要中更新值可以解决问题.这个问题的方法比我在这个答案中所做的更接近.