web-dev-qa-db-ja.com

angular.js配列から要素/ノードを削除する方法

ビュー$scope.itemsでアイテムが削除されるように、配列ng-repeat="item in items"から要素を削除しようとしています

デモ用のコードは次のとおりです。

for(i=0;i<$scope.items.length;i++){
    if($scope.items[i].name == 'ted'){
      $scope.items.shift();
    }
}

名前が正しく入力されている場合、ビューから最初の要素を削除したいですか?正常に機能しますが、ビューはすべての要素をリロードします。すべての配列キーがシフトしているため。これは、私が作成しているモバイルアプリに不必要な遅延を生じさせています。

誰もこの問題の解決策を持っていますか?

69
TheNickyYo

配列からアイテムを削除することにはロケット科学はありません。配列からアイテムを削除するには、 splice$scope.items.splice(index, 1);を使用する必要があります。 ここに例があります

HTML

<!DOCTYPE html>
<html data-ng-app="demo">
  <head>
    <script data-require="[email protected]" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body>
    <div data-ng-controller="DemoController">
      <ul>
        <li data-ng-repeat="item in items">
          {{item}}
          <button data-ng-click="removeItem($index)">Remove</button>
        </li>
      </ul>
      <input data-ng-model="newItem"><button data-ng-click="addItem(newItem)">Add</button>
    </div>
  </body>
</html>

JavaScript

"use strict";

var demo = angular.module("demo", []);

function DemoController($scope){
  $scope.items = [
    "potatoes",
    "tomatoes",
    "flour",
    "sugar",
    "salt"
  ];

  $scope.addItem = function(item){
    $scope.items.Push(item);
    $scope.newItem = null;
  }

  $scope.removeItem = function(index){
    $scope.items.splice(index, 1);
  }
}
132
madhead

この質問に戻る人のために。配列から項目を削除するための正しい「Angular Way」は、$ filterを使用することです。コントローラに$ filterを挿入して、次の操作を実行します。

$scope.items = $filter('filter')($scope.items, {name: '!ted'})

追加のライブラリをロードしたり、Javascriptプリミティブに頼ったりする必要はありません。

120
bpaul

プレーンなjavascriptを使用できます- Array.prototype.filter()

$scope.items = $scope.items.filter(function(item) {
    return item.name !== 'ted';
});
14
Bogdan D

配列でshift()を実行すると、配列の長さが変更されるためです。そのため、forループが台無しになります。この問題を回避するために、を最後から前へループすることができます。

ところで、配列の最初の要素ではなく、位置iの要素を削除しようとすると仮定します。 (コード内の$scope.items.shift();は配列の最初の要素を削除します)

for(var i = $scope.items.length - 1; i >= 0; i--){
    if($scope.items[i].name == 'ted'){
        $scope.items.splice(i,1);
    }
}
11
zs2020

ここにfilterがあります nderscore library 役立つかもしれませんが、「ted」という名前のアイテムを削除します

$scope.items = _.filter($scope.items, function(item) {
    return !(item.name == 'ted');
 });
8
Maxim Shoustin

「角度」ソリューションのほんのわずかな拡張。数値IDに基づいてアイテムを除外したかったので、!アプローチが機能しません。 {name: 'ted'}または{id:42}で機能するより一般的なソリューションは次のとおりです。

mycollection = $filter('filter')(myCollection, { id: theId }, function (obj, test) { 
                                                             return obj !== test; });
6
Mark Farmiloe

@madheadが提供するソリューションが気に入った

しかし、私が持っていた問題は、ソートされたリストでは機能しないため、削除関数にインデックスを渡す代わりに、アイテムを渡してからindexof経由でインデックスを取得したことです

例えば。:

var index = $scope.items.indexOf(item);
$scope.items.splice(index, 1);

Madheadsの例の更新バージョンは以下のとおりです。 例へのリンク

HTML

<!DOCTYPE html>
<html data-ng-app="demo">
  <head>
    <script data-require="[email protected]" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body>
    <div data-ng-controller="DemoController">
      <ul>
        <li data-ng-repeat="item in items|orderBy:'toString()'">
          {{item}}
          <button data-ng-click="removeItem(item)">Remove</button>
        </li>
      </ul>
      <input data-ng-model="newItem"><button data-ng-click="addItem(newItem)">Add</button>
    </div>
  </body>
</html>

JavaScript

"use strict";

var demo = angular.module("demo", []);

function DemoController($scope){
  $scope.items = [
    "potatoes",
    "tomatoes",
    "flour",
    "sugar",
    "salt"
  ];

  $scope.addItem = function(item){
    $scope.items.Push(item);
    $scope.newItem = null;
  }

  $scope.removeItem = function(item){
    var index = $scope.items.indexOf(item);
    $scope.items.splice(index, 1);
  }
}
5
TrtlBoy

これに対する私の解決策(パフォーマンスの問題は発生していません):

  1. メソッドremoveを使用して配列オブジェクトを拡張します(2回以上必要になると確信しています)。
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.Push.apply(this, rest);
};

私はすべてのプロジェクトでそれを使用しています。クレジットはJohn Resigにあります John Resigのサイト

  1. ForEachと基本チェックの使用:
$scope.items.forEach(function(element, index, array){
          if(element.name === 'ted'){
              $scope.items.remove(index);
          }
        });

最後に、angularjsで$ digestが起動され、認識可能な遅延なしにUIがすぐに更新されます。

3
Fer To

IndexOf関数を使用しても、RESTリソースのコレクションではカットされませんでした。

リソースのコレクションにあるリソースの配列インデックスを取得する関数を作成する必要がありました。

factory.getResourceIndex = function(resources, resource) {
  var index = -1;
  for (var i = 0; i < resources.length; i++) {
    if (resources[i].id == resource.id) {
      index = i;
    }
  }
  return index;
}

$scope.unassignedTeams.splice(CommonService.getResourceIndex($scope.unassignedTeams, data), 1);
1
Stephane

Listに関連付けられた関数がある場合、スプライス関数を作成すると、関連付けも削除されます。私の解決策:

$scope.remove = function() {
    var oldList = $scope.items;
    $scope.items = [];

    angular.forEach(oldList, function(x) {
        if (! x.done) $scope.items.Push( { [ DATA OF EACH ITEM USING oldList(x) ] });
    });
};

リストパラメータは名前が付けられています アイテム。パラメーター x.done アイテムが削除されるかどうかを示します。お役に立てば幸いです。ご挨拶。

1
Drako

私の解決策は非常に簡単でした

app.controller('TaskController', function($scope) {
 $scope.items = tasks;

    $scope.addTask = function(task) {
        task.created = Date.now();
        $scope.items.Push(task);
        console.log($scope.items);
    };

    $scope.removeItem = function(item) {
        // item is the index value which is obtained using $index in ng-repeat
        $scope.items.splice(item, 1);
    }
});
1
Bastin Robin

私のアイテムには一意のIDがあります。アンギュラー$filterサービスでモデルをフィルタリングすることで削除しています:

var myModel = [{id:12345, ...},{},{},...,{}];
...
// working within the item
function doSthWithItem(item){
... 
  myModel = $filter('filter')(myModel, function(value, index) 
    {return value.id !== item.id;}
  );
}

Idとして、モデルアイテムの$$ hashKeyプロパティを使用することもできます:$$hashKey:"object:91"

0
Ruwen