10

構文がエレガントで読みやすいので、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 が更新されないようです。そのため、フィルターとは関係のないことが起こっているようです。

4

2 に答える 2

5

angular では、特別な$scope変数を使用してデータを変更します。コントローラー内では、実行コンテキストとして をthis指していることが推奨されます。$scope$scope

UI が更新されない場合、通常は「モデル」(または特定のスコープのプロパティ) の変更が角度の外側で行われたことが原因です。この場合、への呼び出し$applyが必要です。これにより、Angular に何かが変更されたことと、ビューを更新することが通知されます。

ただし、これはあなたの問題ではないようです。ここに最小限の変更を加えた作業リストがありますhttp://plnkr.co/edit/Cnj0fEHSmi2L8BjNRAf5?p=preview

コントローラーの内容は次のとおりです。UIclearList()から呼び出すと、チェックされた項目だけがリストに残ります。

$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 に渡すclearList(list)か、Angular フィルターを使用することをお勧めします。

于 2012-12-14T22:06:25.227 に答える
4
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配列が、後で確認する配列と同じであると確信していますか?

于 2012-12-14T20:43:00.280 に答える