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

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以供参考.

Pan*_*kar 7

正如您@在此处使用的那样,需要来自具有{{}}插值指令的属性的值.并且似乎指令首先被加载然后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回答的原因是因为他使用=提供了双向绑定,而代码并没有让观察者直接从隔离范围中获取值,这里是代码.因此,没有摘要周期,价值会得到更新.


dfs*_*fsq 6

显然它与范围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明确指出,在下一个摘要中更新值可以解决问题.这个问题的方法比我在这个答案中所做的更接近.