Javascript 一组对象上的角度$watch

Javascript 一组对象上的角度$watch,javascript,arrays,angularjs,object,Javascript,Arrays,Angularjs,Object,假设我有一个绑定到我的范围的动物对象数组。每个对象都有一个“名称”属性和一个“声音”属性 然后,我观察数组并将objectEquality标志设置为true,以显示第三个参数 在我看来,我使用动物数组的ng repeat为每个动物创建了一个按钮。然后,我将单击处理功能传递给相应的动物对象 在click处理程序中,如果我要更新其中一个动物的名称,$watch将获取更改,我可以在listener函数中处理它 现在我面临的问题是,如果我用一个新对象重新分配一个动物对象,而不是仅仅更改其属性,$watc

假设我有一个绑定到我的范围的动物对象数组。每个对象都有一个“名称”属性和一个“声音”属性

然后,我观察数组并将objectEquality标志设置为true,以显示第三个参数

在我看来,我使用动物数组的ng repeat为每个动物创建了一个按钮。然后,我将单击处理功能传递给相应的动物对象

在click处理程序中,如果我要更新其中一个动物的名称,$watch将获取更改,我可以在listener函数中处理它

现在我面临的问题是,如果我用一个新对象重新分配一个动物对象,而不是仅仅更改其属性,$watch不会接受此更改。对象数组已明显更改,但我的侦听器未被调用

以下是我刚才概述的示例:


这与AngularJS无关 第一件事——永远记住JavaScript是通过值传递的 这是什么意思?让我们看两种情况:基本体、数组和对象

原语-只需将值传递给函数。因此,如果将初始化的变量作为函数参数传递到函数外部,则对函数内部的值所做的更改不会更改函数外部的值

函数testPrimitiveprm{ prm=prm+1; }

var-prm=1; 测试原始PRM; console.logprm//prm将填充1

对象和数组-此处传递的值是对象的引用。因此,问题是如何反映传递给函数的对象的不断变化的属性,而如果整个对象是新创建的,则这些变化不会反映。让我们举个例子

var foo={id:1,名称:'iamfoo'},bar={id:2,名称:'iambar'}; //这里创建了两个对象,比如在内存ref1和ref2中的某个引用处,//内存位置被分配给foo和bar

函数更新bjo1,o2{ o1.name='changed'; //对象o1不是新创建的。它只接受引用并更新属性。 o2={id:3,名称:'iamnew'}; //将在引用中创建一个新对象,例如“ref3”,并且将ref3指定给o2。注意,此处的ref1仍然保持不变 }

更新bjfoo,bar//此处传递ref1和ref2内存位置值

console.logfoo//foo将是{id:1,名称:'changed'} 控制台.logbar; //由于bar仍然具有ref1内存位置值,所以bar将为{id:2,名称:'iambar'}

在本例中,您正在传递一个命令,在数组中创建一个新对象并分配引用。一旦超出函数循环,引用将丢失,并且不能在任何地方使用; 试试动物名;动物。声音class='baaaa';而是在你的函数中

这是一篇很好的文章:


虽然我觉得这些看起来像是大多数人都不知道或很困惑的基本问题。

尝试将$index作为参数传递给函数,然后执行以下操作

$scope.animals[index] = {name:'Billy', sound:'baaaa'};

这样就可以了

您可以使用$watchcollectionnot work。这是一个很好的例子。我的感觉是,它正在更改对对象的引用,而$watch正在查找对对象的旧引用的属性更改。我可能已经完全关闭了。我以前没有注意到这一点,但是你的changeObject函数并不能替换数组中的任何东西。它将动物变量的引用从数组中的对象更改为在该函数中实例化的对象。此外,您应该首先通过在其中设置$watch函数来发布您试图解决的问题的更广泛范围。据我从Plunker中所知,您只是将$scope.animals分配给$scope.result,这似乎不是很有用。感谢您的回复。我知道原语是通过值传递的,对象是通过引用传递的。但我没有意识到的是,即使对象是通过引用传递的,它也只是引用位置的副本。因此,当您为该对象指定一个新引用时,它将不会在该函数之外持久化。