2012-12-14 76 views
3

我想使用Javascript的array.filter从数组中删除项目,因为语法优雅且可读。但是,似乎过滤器不会修改原始数组,它只是返回一个新数组,并按您的要求进行过滤。我的问题是,为什么不按照我的预期工作?使用Javascript修改原始数组Array.Filter

$scope.clearList = function() { 
    this.list = this.list.filter(function (item) { 
    return item.checked == true; 
    }); 

    //... 
} 

我认为在返回新过滤的数组之后,this.list现在只能保存已过滤的数组。然而,它不能像这样工作。 this.list最终包含完全相同的项目。更改代码以将过滤数组保存在中间变量中表明它确实正确过滤。

我已经完成了一个解决方案,循环浏览过滤版本,并将应该过滤的原始列表中的项目拼接起来,但这不够雅观。我只是在想它是错误的方式?


旁注:我使用的是Angular.js。我不能确定它在所有,但名单来自于以下几个:

<div class="list" ng-repeat="list in lists"> 
    <!-- ... --> 
    <ul> 
     <li ng-repeat="item in list"> 
     <div> 
      <label> 
      <input type="checkbox" ng-model="item.checked"/> 
      {{item.name}} 
      </label> 
      <!-- ... --> 
     </div> 
     </li> 
    </ul> 
    <button class="btn clear-selected" ng-click="clearList()"> 
     Remove Selected 
    </button> 
    </div> 

编辑添加调试信息:我介绍了一个临时变量只是为了看看什么在调试正在进行。

var temp = this.list.filter(function (item) { 
    return item.checked == true; 
}); 

this.list = temp; 

执行前,this.List有5个项目,temp是未定义的。 第一行执行后,this.List有5个项目,temp有2个项目。 最后一行执行后,this.List有2个项目,temp有2个项目。

但是,在此之后,绑定到this.list的UI不会更新。因此,与过滤器无关的事情似乎正在进行。

+1

嗯,我已经做了一个涉及foreach的解决方法。它似乎必须有一个更清洁的方式。此外,你是不是应该修改你正在播放的歌曲集,例如从中删除物品?我知道在C#.NET中这是真的。 – jtheis

+0

是的,我早点读错了你的问题。删除了我以前的评论。 – bits

+0

你有一个地方的例子页面吗?这可能有帮助。唯一让我困惑的是你过滤this.list,并且没有看到任何$ scope。我可能会遇到一些错误,但除非您的列表是$ scope的一个属性,否则UI无法更新。哦,还有一件事:你在指令中有一个指令(列表属于第一个ng-repeat的范围,据我记忆)这可能非常棘手,我猜测错误在某处。但也许我错了:) –

回答

3

通过使用特殊的$scope变量修改数据,并且在控制器内部this指向$scope作为执行上下文,$scope是首选。

当UI不更新时,通常是因为“模型”(或给定范围的属性)中的更改是在角度外完成的。在这种情况下,需要致电$apply。这通知角色已经发生了变化并更新了视图。

但是,这似乎不是你的问题。我在这里最小的变化http://plnkr.co/edit/Cnj0fEHSmi2L8BjNRAf5?p=preview

一个工作列表下面是控制器的内容,当你从UI调用clearList(),只有检查的项目留在列表中。

$scope.list = [ 
    {name: 'one', checked: true}, 
    {name: 'two', checked: false}, 
    {name: 'three', checked: true}, 
    {name: 'four', checked: false} 
]; 

$scope.clearList = function() { 
    $scope.list = $scope.list.filter(function(item) { 
    return item.checked === true; 
    }); 
}; 

现在,我建议通过清单清单clearList(list)或甚至更好地使用Angular过滤器。

+0

将'list'传递给'clearList'运行良好,并且使用角度过滤器,我甚至不需要传入'list'。在这种情况下'this.list'工作得很好。谢谢! – jtheis

2
window.list = [1,2,3,4,5,6]; 
var clearList = function() { 
    this.list = this.list.filter(function (item) { return item % 2 === 0; }); 
}; 
clearList(); 
console.log(window.list); 

日志[2, 4, 6]如预期,所以我觉得无论你的错误是无关filter

您确定您正在使用this.list修改的数组与您稍后要检查的数组相同吗?

+0

看来它可能不是。我已经添加了额外的信息来显示我在调试器中看到的问题。 – jtheis