我试图弄清楚为什么我无法覆盖通过隔离范围(@)传递给angularJS指令的值。我尝试vm.index使用以下方法覆盖的值:
@
vm.index
vm.index = parseInt(vm.index, 10)
但是,由于某些原因,它不起作用。
如果我将其更改为:
vm.newIndex = parseInt(vm.index, 10)
有用。另外,在$scope作品上分配价值。
$scope
为什么第一种方法不起作用?
我已经创建了这个示例插件。
如您@在此处使用的那样,需要通过{{}}插值指令从属性获取值。似乎指令首先被加载,然后vm.index值被求值。因此,在当前摘要周期中不会发生更改。如果希望这些内容得到反映,则需要使用$ timeout以更安全的方式运行摘要循环。
{{}}
$timeout(function(){ vm.index = parseInt(vm.index, 10) })
上面的事情是确保将值转换为十进制值。加法将出现在指令html上<h2>Item {{ vm.index + 1 }}</h2>
<h2>Item {{ vm.index + 1 }}</h2>
工作演示
根据@dsfq和我的讨论,我们遍历了angular $compile API,发现它们是一个方法调用 initializeDirectiveBindings ,仅当我们controllerAs在具有隔离范围的in指令中使用时才调用。在这个功能有开关的情况下的各种结合@,=并且&,这样你使用@,这意味着一个双向绑定下面的开关情况下的代码被调用。
$compile
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;
在上面的代码中,您可以清楚地看到它们放置在attrs.$observe其中,这是一种观察者,通常在值与插值一起使用时(例如在我们的示例中是相同的){{index}},这意味着$observe在摘要循环运行时会对其进行评估,这就是为什么需要$timeout在创造index价值的同时投入decimal。
attrs.$observe
{{index}}
$observe
$timeout
index
decimal
@dsfq答案之所以有效,是因为他使用=了提供两种方式的绑定,这些代码不会使观察者直接从隔离的范围中获取值, 这是代码 。因此,没有摘要循环,该值将被更新。