AngularJS Scope监视以查找更改了哪个绑定属性

时间:2014-09-27 15:16:52

标签: angularjs angularjs-scope

我正在编写一个程序,我在其中查看我的范围内的数组。 Scope.watch根据需要运行,它为我提供了修改后的值。但是,我如何找出哪个元素已被更改?

for(var i=0; i<5; i++) {
    myarray[i] = "var_" + i;
}

Scope.$watch(myarray[i], function (newValue,OldValue) {
    alert(myarray[i]); // Doesn't give me the correct value changed attributes because i has been modified
});

我如何知道哪些属性已被更改,例如:var_1,var_2?

3 个答案:

答案 0 :(得分:2)

如果您的代码看起来像这样:

for(var i=0;i<5;i++)
{
    myarray[i] = "var_" + i;
}

Scope.$watch(myarray[i], function (newValue,OldValue) {
    alert(myarray[i])
}

然后答案很简单。 var_4更改后,您的手表将始终触发。

为什么?

这是因为您在for循环范围之外创建了手表。由于变量作用域在JavaScript中的作用方式,循环变量的作用域是函数,所以你的代码仍然可以工作,但是没有做到你期望的那样 - i的值{{1}将是循环中的最后一个值。

如果要指定要在循环中观察的范围变量,您可以执行以下操作:

Scope.$watch(myarray[i], ...)

这将为每个循环迭代创建一个新监视,并通过中间函数作用域传递变量名称将确保它是正确的。

说了这么多,如果您发现自己需要在循环中创建手表,我相当确定您做错了。如果你要解释你想要完成什么,我们或许能够提供一个更有意义的答案。例如,如果您想要观察范围变量var_1和var_2,您可以简单地:

for(var i=0;i<5;i++)
{
    myarray[i] = "var_" + i;

    Scope.$watch(myarray[i], function (varName) { 
        return function (newValue,OldValue) {
            alert(varName + "changed, new value: " + newValue);
        }
    }("var_" + i));
}

如果您需要观察对任意长度数组的更改并知道更改的索引,可以尝试这样做:

Scope.$watch("var_1", function (newValue,OldValue) {
    alert("var_1 changed: " + myarray[i])
}

Scope.$watch("var_2", function (newValue,OldValue) {
    alert("var_2 changed: " + myarray[i])
}

我仍然相当确定这不是你想要做的事情,但考虑到我们对这个问题的了解,这是我能做的最好的事情。但我猜你可能想要将function firstDifferetIndex(a1, a2) { for (var i = 0; i < a1.length; i++) { if (a1[i] != a2[i]) { return i; } } return -1; } Scope.$watchCollection("[" + myarray.join(",") + "]" , function (new, old) { var changedIndex = firstDifferentIndex(new, old); alert("var_" + changedIndex + " changed"); }); 与自定义指令结合起来以更清洁的方式获得你想要的东西。

答案 1 :(得分:0)

您可以使用hack:Demo

scope.myArray = [];

for(var i=0; i<5; i++) {
    scope.myArray[i] = { text: "var_" + i, id: i };

    scope.$watch("myArray." + i, function (new, old) {
        console.log("Changed Variable", scope.myArray[new.id].text);
        console.log("Index", old.id); // Or new.id as long as you don't modify them.
    }, true);
}

因此,如果您需要找出更改的元素,请使用old.idnew.id

答案 2 :(得分:0)

我发现此$scope.$$watcher的解决方案包含范围正在观看的所有属性。迭代$$观察者并检查其上的最后一个值($watch.last),然后在eval中有属性的名称。因此,将newvalue与$ watch.last属性进行比较,并从watch中获取属性的名称诀窍。

我将很快使用示例编辑此答案:Code