Bagaimana cara menghapus item dari array di lingkup AngularJS?

153

Agenda yang harus dilakukan, tetapi dengan tombol hapus pada halaman daftar untuk setiap item:

masukkan deskripsi gambar di sini

HTML templat yang relevan:

<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>

Metode pengontrol yang relevan:

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

Saya mencoba $scope.persons.pull(person)dan $scope.persons.remove(person).

Meskipun database berhasil dihapus, saya tidak bisa menarik item ini dari ruang lingkup dan saya tidak ingin membuat panggilan metode ke server untuk data yang sudah dimiliki klien, saya hanya ingin menghapus orang ini dari ruang lingkup.

Ada ide?

Sampai jumpa
sumber
Saya menjalankan $ rute ini, dan tampilan tidak akan berfungsi dengan baik. Saya selalu mendapat halaman kosong setelah saya menghapus :-(
zx1986
Telah menulis artikel serupa codepedia.info/angularjs-delete-table-row-tr-on-click
Satinder singh
ini bukan tentang menghapus dari lingkup tetapi dari array, dan itu akan menjadi sama terlepas dari sudut, hanya javascript
nya

Jawaban:

259

Masalah Anda sebenarnya bukan dengan Angular, tetapi dengan metode Array. Cara yang tepat untuk menghapus item tertentu dari array adalah dengan Array.splice. Juga, ketika menggunakan ng-repeat, Anda memiliki akses ke $indexproperti khusus , yang merupakan indeks saat ini dari array yang Anda lewati.

Solusinya sebenarnya cukup mudah:

Melihat:

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

Pengendali:

$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);
  });
};
Josh David Miller
sumber
1
@ScottMalachowski Anda benar. Saya lupa bagian itu. Saya merevisi jawaban saya untuk mencerminkan itu, jadi itu akan konsisten dengan Anda.
Josh David Miller
13
Hati-hati - solusi berbasis indeks ini tidak akan berfungsi jika Anda menggunakan multi-pengulangan dari objek yang sama dalam tampilan (mis. Tugas Terjadwal, Tugas Tidak Terjadwal, Tugas Selesai semua keluar dari $ scope.tasks) karena Anda akan memiliki beberapa item dengan indeks 2, 3, 4, dll.
shacker
Komentar di atas, oleh @shacker, tentang beberapa pengulangan dengan set filter yang berbeda dari array yang sama, sudah aktif. Gunakan metode di bawah ini dengan indexOf
Andrew Kuklewicz
4
@AndrewKuklewicz - indexOfbisa menjadi operasi yang lebih mahal; tanpa penyaringan, itu sama sekali tidak perlu. Tetapi dengan penyaringan, indexOfakan menjadi metode yang tepat.
Josh David Miller
Saya berjuang dengan ini dan harus membuat perubahan kecil pada pembuatan tag di atas - being - delete ({{$ index}}) dengan {{}} jika tidak, saya mendapatkan string $ index - TAPI saya memiliki sesuatu yang salah karena itu tidak pernah menyebut metode itu. Itu terjadi ketika saya menghapus penyebutan indeks seperti delete () tapi itu tidak terlalu membantu.
mikemil
310

Anda harus menemukan indeks persondalam personsarray Anda , lalu gunakan metode array splice:

$scope.persons.splice( $scope.persons.indexOf(person), 1 );
Joseph Silber
sumber
49
ini jawaban yang lebih baik; berfungsi ketika daftar telah disaring sehingga indeks dalam tampilan tidak sama dengan dalam array dalam lingkup.
Andrew Kuklewicz
5
Ini memang jawaban yang lebih baik. Perhatikan bahwa selain kasus penggunaan daftar yang difilter yang disebutkan oleh Andrew, pendekatan ini juga mencakup kasus di mana Anda menghapus beberapa orang dan permintaan Ajax untuk penghapusan ini kembali tidak sesuai pesanan. Jika Anda telah menggunakan indeks baris sebelum panggilan Ajax kembali, Anda akan menghapus baris yang salah.
Joris
4
Lebih baik dalam beberapa kasus, tetapi dengan indexOf Anda harus beralih pada semua item untuk menemukan yang tepat, dalam jawaban Josh Anda mendapatkan indeks dan item lebih cepat
daver
@mike - Gunakan polyfill ini .
Joseph Silber
8

Saya akan menggunakan perpustakaan Underscore.js yang memiliki daftar fungsi yang berguna.

without

without_.without(array, *values)

Mengembalikan salinan array dengan semua instance nilai yang dihapus.

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

Contoh

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

Lihat Demo di JSFiddle .


filter

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

// => [2, 4, 6]

Contoh

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

Lihat Demo di Fiddle .

Maxim Shoustin
sumber
Saya mungkin akan menggunakan $scope.nodes = _.without($scope.nodes, node);karena dia memiliki referensi kenode
jake
Pada browser modern yang dapat Anda gunakan Array.prototype.filter. _.filter(array, fun)menjadi array.filter(fun).
bfontaine
7
$scope.removeItem = function() {
    $scope.items.splice($scope.toRemove, 1);
    $scope.toRemove = null;
};

ini bekerja untuk saya!

cebor
sumber
4

Jika Anda memiliki fungsi yang terkait dengan daftar, ketika Anda membuat fungsi sambatan, asosiasi tersebut juga dihapus. Solusi saya:

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

Param daftar bernama item . Param x.done menunjukkan jika item tersebut akan dihapus.

Referensi lain: Contoh lain

Semoga bisa membantu Anda. Salam pembuka.

Drako
sumber
2

Untuk jawaban yang diterima dari @Joseph Silber tidak berfungsi, karena indexOf mengembalikan -1. Ini mungkin karena Angular menambahkan hashkey, yang berbeda untuk $ scope.items [0] saya dan item saya. Saya mencoba menyelesaikan ini dengan fungsi angular.toJson (), tetapi tidak berhasil :(

Ah, saya menemukan alasannya ... Saya menggunakan metode chunk untuk membuat dua kolom di meja saya dengan menonton $ scope.items saya. Maaf!

gabn88
sumber
2

Anda juga bisa menggunakan ini

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

Angular memiliki fungsi bawaan yang disebut arrayRemove, dalam kasus Anda metode ini dapat berupa:

arrayRemove($scope.persons, person)
Allen
sumber
1
array.splice(array.pop(item));
Taran
sumber
0

Untuk menghapus elemen dari ruang lingkup gunakan:

// remove an item
    $scope.remove = function(index) {
        $scope.items.splice(index, 1);
    };

Dari masukkan uraian tautan di sini

Cubiczx
sumber