Javascript orderBy$filter blocks ng项目删除后重复列表更新(拼接)

Javascript orderBy$filter blocks ng项目删除后重复列表更新(拼接),javascript,angularjs,angularjs-filter,angularjs-orderby,Javascript,Angularjs,Angularjs Filter,Angularjs Orderby,我有一个显示为ng repeat并按名称desc排序的列表 每个项目上都有一个item delete指令,该指令保存$index,在项目上单击我使用给定的index和拼接功能从列表中删除项目,然后我更新列表-这不起作用 根据我的调试结果,问题发生在orderByfilter被称为inside指令之后。如果我像这样直接删除项目scope.list.splice(index,1),它可以工作,但是删除的项目不是正确的项目,因为项目是通过ng repeat排序的,所以我必须以相同的方式排序,然后我可以

我有一个显示为ng repeat并按名称desc排序的列表

每个项目上都有一个
item delete
指令,该指令保存
$index
,在项目上单击我使用给定的
index
拼接
功能从列表中删除项目,然后我更新列表-这不起作用

根据我的调试结果,问题发生在
orderBy
filter被称为inside指令之后。如果我像这样直接删除项目
scope.list.splice(index,1)
,它可以工作,但是删除的项目不是正确的项目,因为项目是通过ng repeat排序的,所以我必须以相同的方式排序,然后我可以执行正确的删除

一个解决方法是
$emit
新列表并更新控制器内的作用域,但我不想这样做。已测试并正在工作(请参阅代码段)

作用域。$apply
将遇到一个已经在进行中的
摘要
错误(因为这部分代码在我的应用程序的承诺内)&如果没有
$timeout
列表在工作时不会更新(例如,使用
noFilter
filter)

*我使用一个指令从列表中删除一个项,因为我在单击项时做了很多事情(DOM更改、服务调用),而控制器不是这样做的地方(以防您在想为什么我没有通过控制器来执行此操作)

还有一个plnkr

//JS
var-APP=angular.module('APP',[]);
应用程序控制器('Home',函数($scope,$filter){
变量objData={
“1”:{id:1,名称:“Abc”},
“2”:{id:2,姓名:“Bbc”},
“3”:{id:3,名称:“Fea”},
“4”:{id:4,名称:“Dbc”}
};
$scope.list=$filter('objtoar')(objData);
//解决方案的一部分。。。
$scope.$on('listUpdate',函数(evt,数据){
$scope.list=数据;
})
}); 
APP.directive('itemDelete',函数($filter,$timeout){
返回{
限制:“A”,
链接:功能(范围、el、属性){
德林德风险;
属性$observe('itemDelete',函数(val){
delIndex=val;
});
元素(el).单击(函数(){
console.log('deleting item index'+delIndex);
log('前面的列表长度+scope.list.length);
//从ng重复订购列表中删除项目
$timeout(函数(){
var listOrdered=$filter('orderBy')(scope.list,'-name');//将'orderBy'替换为'noFilter'->它可以工作,但删除了错误的项!
//var listOrdered=scope.list;//在此之前取消注释和注释行->它起作用,但删除了错误的项!
拼接(delIndex,1);
scope.list=listOrdered;
//解决方法。。。
//scope.$emit('listUpdate',scope.list);
log('+scope.list.length之后的列表长度);
});
});
}
}
})
APP.filter('objToArr',function(){
返回函数(输入){
var-arrData=[];
角度forEach(输入,功能(arr,键){
arrData.push(arr);
});
返回数据;
}
});
APP.filter('noFilter',function(){
返回函数(输入){
返回输入;
}
});
ulli{显示:块;页边距底部:4px;背景色:#ccc;填充:5px;}
ul{列表样式:无;}

单击项目-从列表中删除
  • {{{item.name}

问题出在这一行:

scope.list = listOrdered;
该行在chlid作用域上定义一个新的
list
属性,而不是更改作为父作用域属性的实际列表。(这样做的范围。$parent.list=listOrdered可以正常工作.)

您可以通过将列表放在对象中来解决此问题,这将使引用保持同步:

$scope.objList = { list: $filter('objToArr')(objData) };

var listOrdered = $filter('orderBy')(scope.objList.list, '-name'); //replace 'orderBy' with 'noFilter' -> it works, but removes wrong item!
listOrdered.splice(delIndex,1);
scope.objList.list = listOrdered;
在HTML中:

<li item-delete="{{ $index }}" ng-repeat="item in objList.list | orderBy:'-name'">{{ item.name }}</li>
  • {{item.name}

  • 检查此项

    是否有理由尝试构建复杂指令来处理此任务?有很多更简单的方法来完成您在这里展示的内容……图标更改、禁用所有内容(位置更改、所有页面操作)、服务调用和等待承诺,并在此基础上(win&err)对模型和DOM进行更改。这就是这个指令中发生的事情。给我举一些其他方法的例子,也许我可以适应我的需要。我可以使用ng click呼叫服务并在controller中等待回答,当我得到它时,我可以使用ng类更改图标…但我很好奇为什么不这样做。好的。。。但是如果你把这个
    $timeout(function(){var listOrdered=$filter('orderBy')($scope.list,'-name');listOrdered.splice(2,1);$scope.list=listOrdered;},2000)控制器内部,它可以工作。为什么?它会起作用,因为您在列表的同一范围内更改了属性。我已经澄清了我的答案。查看这里了解更多信息:明白了!我记得我在我的应用程序中尝试了
    scope.$parent
    ,但没有成功,但在这里成功了。。。稍后我将再次运行一些测试。很好的解释,谢谢!。。。我和noFilter的代码行是有效的,因为我没有改变任何东西,我只是返回给我的东西。还是。。。我有另一个页面,在那里我做的几乎相同,但是我没有使用
    orderBy
    ,而是使用一个自定义的orderBy过滤器(它返回一个修改过的列表),并且列表保持同步。