AngularJSスコープの配列からアイテムを削除するにはどうすればよいですか?


153

簡単なTo Doリストですが、各アイテムのリストページに削除ボタンがあります。

ここに画像の説明を入力してください

関連するテンプレートHTML:

<tr ng-repeat="person in persons">
  <td>{{person.name}} - # {{person.id}}</td>
  <td>{{person.description}}</td>
  <td nowrap=nowrap>
    <a href="#!/edit"><i class="icon-edit"></i></a>
    <button ng-click="delete(person)"><i class="icon-minus-sign"></i></button>
  </td>
</tr>

関連するコントローラーメソッド:

$scope.delete = function (person) {
  API.DeletePerson({ id: person.id }, function (success) {
    // I need some code here to pull the person from my scope.
  });
};

私が試した$scope.persons.pull(person)$scope.persons.remove(person)

データベースは正常に削除されましたが、このアイテムをスコープからプルすることはできず、クライアントが既に持っているデータをサーバーにメソッド呼び出ししたくありません。この1人をスコープから削除したいだけです。

何か案は?


この聖なる$ routeを実行すると、ビューが正常に機能しなくなります。削除した後、常に空のページが表示されました:-(
zx1986


これはスコープからの削除ではなく、配列からの削除です。角度に関係なく同じ
です。JavaScript

回答:


259

あなたの問題は実際にはAngularではなく、Arrayメソッドにあります。配列から特定の項目を削除する適切な方法は、を使用することArray.spliceです。また、ng-repeatを使用$indexする場合、渡した配列の現在のインデックスである特別なプロパティにアクセスできます。

解決策は実際には非常に簡単です:

見る:

<a ng-click="delete($index)">Delete</a>

コントローラ:

$scope.delete = function ( idx ) {
  var person_to_delete = $scope.persons[idx];

  API.DeletePerson({ id: person_to_delete.id }, function (success) {
    $scope.persons.splice(idx, 1);
  });
};

1
@ScottMalachowskiそうですね。その部分を忘れました。私はそれを反映するように私の回答を修正したので、あなたの回答と一致するでしょう。
Josh David Miller、

13
注意-このインデックスベースのソリューションは、ビューで同じオブジェクトの複数のng-repeatsを使用する場合は機能しません(例:スケジュールされたタスク、スケジュールされていないタスク、完了したタスクはすべて$ scope.tasksから取得されます)。インデックス2、3、4など
ハッカー

@shackerによる上記のコメントは、同じ配列の異なるフィルター済みセットを使用した複数のng-repeatsに関するものです。以下のメソッドをindexOfで使用する
Andrew Kuklewicz 2013

4
@AndrewKuklewicz- indexOfより高価な操作になる可能性があります。フィルタリングなしでは、それは完全に不要です。しかし、フィルタリングでindexOfは、適切な方法になります。
Josh David Miller

私はこれに苦労していて、上記のタグの生成にマイナーな変更を加える必要がありました-{{}}を使用して-delete({{$ index}})です。そのメソッドを呼び出すことはありません。delete()のようなインデックスへの言及を削除した場合に実行されますが、実際には役に立ちません。
mikemil 2013年

310

配列ののインデックスを見つけて、配列のメソッドを使用する必要がありpersonます。personssplice

$scope.persons.splice( $scope.persons.indexOf(person), 1 );

49
これはより良い答えです。ビューのそのインデックスがスコープ内の配列のインデックスと同じにならないようにリストがフィルターされている場合に機能します。
Andrew Kuklewicz 2013

5
これは確かに良い答えです。Andrewによって言及されたフィルタリングされたリストの使用例に加えて、このアプローチは複数の人を削除し、これらの削除に対するAjax要求が順不同で戻る場合もカバーすることに注意してください。Ajax呼び出しが戻る前の行インデックスを使用していると、誤った行が削除されてしまいます。
Joris

4
場合によってはより優れていますが、indexOfを使用すると、すべてのアイテムを反復処理して適切なアイテムを見つける必要があります
。Joshの


8

便利な関数のリストがあるUnderscore.jsライブラリを使用します。

without

without_.without(array, *values)

値のすべてのインスタンスが削除された配列のコピーを返します。

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
// => [2, 3, 4]

var res = "deleteMe";

$scope.nodes = [
  {
    name: "Node-1-1"
  },
  {
    name: "Node-1-2"
  },
  {
    name: "deleteMe"
  }
];
    
$scope.newNodes = _.without($scope.nodes, _.findWhere($scope.nodes, {
  name: res
}));

JSFiddleのデモを参照してください。


filter

var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });

// => [2, 4, 6]

$scope.newNodes = _.filter($scope.nodes, function(node) {
  return !(node.name == res);
});

Demo in Fiddleを参照してください。


私はおそらく使用したい$scope.nodes = _.without($scope.nodes, node);彼はへの参照があるためnode
ジェイク

最新のブラウザで使用できますArray.prototype.filter_.filter(array, fun)になりarray.filter(fun)ます。
bfontaine 2014

7
$scope.removeItem = function() {
    $scope.items.splice($scope.toRemove, 1);
    $scope.toRemove = null;
};

これは私のために働きます!


4

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) ] });
    });
};

リストパラメータはitemsという名前です。パラメータx.doneは、アイテムが削除されるかどうかを示します。

別の参照:別の例

お役に立てば幸いです。こんにちは。


2

indexOfが-1を返すため、@ Joseph Silberの受け入れられた回答が機能していません。これはおそらく、Angularがハッシュキーを追加するためです。これは、$ scope.items [0]とアイテムでは異なります。angular.toJson()関数でこれを解決しようとしましたが、うまくいきませんでした:(

ああ、理由がわかりました... $ scope.itemsを見て、チャンクメソッドを使用してテーブルに2つの列を作成します。ごめんなさい!


2

これも使えます

$scope.persons = $filter('filter')($scope.persons , { id: ('!' + person.id) });

1

Angularにはと呼ばれる組み込み関数がarrayRemoveあり、あなたの場合、メソッドは次のようになります:

arrayRemove($scope.persons, person)


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.