为什么我不能像这样覆盖变量的值? [英] Why can't I overwrite the value of a variable like this?

查看:27
本文介绍了为什么我不能像这样覆盖变量的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to figure out why I'm having trouble overwriting a value passed to an angularJS directive via an isolate scope (@). I try to overwrite the value of vm.index with the following:

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

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

However, it doesn't work for some reason.

如果我把它改成:

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

它有效.此外,在 $scope 上分配值也有效.

It works. Also, assigning the value on the $scope works.

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

Why doesn't the first method work?

我创建了这个 示例 plunker 以供参考.

I've created this example plunker for reference.

推荐答案

正如您在此处使用的 @ 一样,它需要来自带有 {{}} 插值指令的属性的值.并且似乎指令首先被加载&然后对 vm.index 值进行评估.所以在当前的摘要周期中没有发生变化.如果您希望反映这些内容,您需要使用 $timeout 以更安全的方式运行摘要循环.

As you used @ here which need value from an attribute with {{}} interpolation directive. And seems like directive is getting loaded first & then the vm.index value is getting evaluated. So the changes are not occurring in current digest cycle. If you want those to be reflected you need to run digest cycle in safer way using $timeout.

$timeout(function(){
  vm.index = parseInt(vm.index, 10)
})

以上是确保将值转换为十进制值.添加将发生在指令 html <h2>Item {{ vm.index + 1 }}</h2>

Above thing is ensuring that value is converted to decimal value. The addition will occur on the on the directive html <h2>Item {{ vm.index + 1 }}</h2>

工作演示

根据@dsfq &我的讨论我们通过了角度 <代码>$compile API,&发现他们是一种方法调用 initializeDirectiveBindings 仅当我们在具有隔离作用域的指令中使用 controllerAs 时才会调用.在这个函数中,有各种绑定 @,=& 的切换案例,所以你正在使用 @ 表示调用以下 switch case 代码的一种方式绑定.

As per @dsfq & my discussion we went through the angular $compile API, & found that their is one method call initializeDirectiveBindings which gets call only when we use controllerAs in directive with an isolated scope. In this function there are switch cases for the various binding @,= and & , so as you are using @ which means one way binding following switch case code gets called.

代码

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.

In above code you can clear see that there they placed attrs.$observe which is one sort of watcher which is generally used when value is with interpolation like in our case it is the same {{index}}, this means that this $observe gets evaluated when digest cycle run, That's why you need to put $timeout while making index value as decimal.

@dsfq 答案之所以有效,是因为他使用 = 提供了两种绑定方式,该绑定不会让观察者直接从隔离范围中获取值,这是代码.因此,如果没有摘要周期,该值就会更新.

The reason @dsfq answer works because he use = provides two way binding which code is not putting watcher directly fetching value from the isolated scope, here is the code. So without digest cycle that value is getting updated.

这篇关于为什么我不能像这样覆盖变量的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆