Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/423.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用$watch更新数据,ng repeat不反映更改_Javascript_Angularjs_Angularjs Directive_Angularjs Ng Repeat - Fatal编程技术网

Javascript 使用$watch更新数据,ng repeat不反映更改

Javascript 使用$watch更新数据,ng repeat不反映更改,javascript,angularjs,angularjs-directive,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Directive,Angularjs Ng Repeat,我在$scope.raw中有一个fooditems列表,我想在列中显示这些数据,所以我稍微改变了结构。我在sortStuff()函数中执行此操作,并将更新的数据存储在$scope.allfood中。有一个$watch,每当$scope.raw中发生任何变化时,它都会调用sortStuff()(我正在使用拖放更改食品类别): 这就是当食物被拖来拖去时发生的情况: receive:function(event, ui) { var issueScope = angular.element(u

我在
$scope.raw中有一个fooditems列表,我想在列中显示这些数据,所以我稍微改变了结构。我在
sortStuff()
函数中执行此操作,并将更新的数据存储在
$scope.allfood
中。有一个$watch,每当
$scope.raw
中发生任何变化时,它都会调用
sortStuff()
(我正在使用拖放更改食品类别):

这就是当食物被拖来拖去时发生的情况:

receive:function(event, ui) {
    var issueScope = angular.element(ui.item).scope();
    scope.$apply(function() {
        var recp = _.find(scope.raw, function(lineitem){
            return lineitem.name === issueScope.receipe.name;
        })
        recp.cat = scope.col.name;
    })

    $(ui.item).remove(); // remove DOM
}
基本上,我在
$scope.raw
中搜索正确的对象,并将
cat
更改为食品的新类别。我还删除了dom元素,因为我指望ng repeat刷新视图。这似乎很好:$watch中的console.log显示对象正在移动到正确的类别,并且数据看起来应该是什么样子。然而,从视觉上看,ng repeat并不能反映数据

将项目从B拖动到C可以正常工作。将一项从A拖动到B,会使B中的两项消失。。。结果非常不一致,我不知道发生了什么


你知道怎么回事吗?或者有什么更好的方法吗?

代码的问题是
ng repeat
指令将属性
$$hashKey
添加到列表中的每个元素。该指令使用此属性将DOM元素与数组元素关联

由于您是通过引用传递元素,
ng repeat
指令将
$$hashKey
属性直接写入
$scope.raw
数组的对象中。一个简单的解决方法是在将对象插入
$scope.allfood
对象之前复制它们

_.each($scope.raw, function(recp){
    recp = _.clone(recp);
    switch(recp.cat){
        ...
    }
});
现在,
ng repeat
更新
$scope.allfood
的对象,而
$scope.raw
的对象保持不变

请参阅更新的小提琴:


您应该使用$watchCollection('raw',function(){});但我已经这么做了,并且仍然在我的应用程序中看到相同的问题…谢谢,这很有效!但有两个问题:是否可以克隆没有由angular添加的属性(如
$$hashKey
)的对象?还有,你认为有更好的方法吗?angular在每次更改时都会重新生成整个
$scope.allfood
,这一事实对性能来说并不好,我想以某种方式避免它。
angular.copy
提供了一种方法,可以创建数组或对象的深度副本,而无需属性,例如
$$hashKey
:您可能可以跟踪对
$scope.raw
数组,仅根据跟踪的更改修改
$scope.allfood
对象。我不认为这会带来显著的性能改进,只要列表很小。angular.copy可以满足我的需要。谢谢
_.each($scope.raw, function(recp){
    recp = _.clone(recp);
    switch(recp.cat){
        ...
    }
});