2012-12-14 77 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