AngularJS kapsamındaki bir diziden bir öğe nasıl kaldırılır?


153

Basit yapılacaklar listesi, ancak her bir öğe için liste sayfasında sil düğmesi ile:

resim açıklamasını buraya girin

Alakalı şablon HTML'si:

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

İlgili denetleyici yöntemi:

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

Denedim $scope.persons.pull(person)ve $scope.persons.remove(person).

Veritabanı başarıyla silindi, ancak bu öğeyi kapsamdan çekemiyorum ve istemcinin zaten sahip olduğu veriler için sunucuya bir yöntem çağrısı yapmak istemiyorum, sadece bu kişiyi kapsamdan kaldırmak istiyorum.

Herhangi bir fikir?


Bu whit $ rotasını çalıştırıyorum ve görünüm iyi çalışmıyor. Silme işlemini yaptıktan sonra her zaman boş bir sayfa aldım :-(
zx1986


bu kapsamdan
silmekle

Yanıtlar:


259

Sorununuz gerçekten Açısal değil, Array yöntemleriyle ilgili. Bir diziden belirli bir öğeyi kaldırmanın uygun yolu ile Array.splice. Ayrıca, ng-repeat kullanırken, geçirdiğiniz $indexdizinin geçerli dizini olan özel özelliğe erişebilirsiniz .

Çözüm aslında oldukça basittir:

Görünüm:

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

Denetleyici:

$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 Haklısın. O kısmı unuttum. Cevabımı bunu yansıtacak şekilde gözden geçirdim, bu yüzden sizinkiyle tutarlı olacak.
Josh David Miller

13
Dikkatli - Bir görünümde aynı nesnenin birden fazla ng tekrarı kullanırsanız (örn. Zamanlanmış Görevler, Planlanmamış Görevler, Tamamlanmış Görevlerin tümü $ scope.tasks öğesinden gelir) işe yaramaz. dizin 2, 3, 4, vb.
shacker

Yukarıdaki yorum, @shacker tarafından, aynı dizinin farklı filtrelenmiş kümeleriyle birden çok ng-tekrarı hakkında açıktır.
İndexOf

4
@AndrewKuklewicz - indexOfdaha pahalı bir işlem olabilir; filtreleme olmadan, tamamen gereksizdir. Ancak filtreleme ile indexOfuygun yöntem olacaktır.
Josh David Miller

Ben bununla mücadele ve yukarıdaki etiket üretimi için küçük bir değişiklik yapmak zorunda - varlık - delete ({{$ index}}) {{}} ile aksi takdirde $ index dizesini aldım - AMA yanlış bir şey var çünkü asla bu yöntemi çağırmaz. Delete () gibi dizinin herhangi bir sözünü kaldırdığımda yapar, ancak bu gerçekten yardımcı olmaz.
mikemil

310

Sen dizinini bulmak gerekecek personsizin de personsdizinin ardından dizinin kullanmak spliceyöntemini:

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

49
bu daha iyi bir cevap; liste filtrelendiğinde çalışır; böylece görünümdeki dizin, kapsamdaki diziyle aynı olmaz.
Andrew Kuklewicz

5
Bu gerçekten daha iyi bir yanıt. Filtrelenmiş listelere Andrew tarafından belirtilen durumun yanı sıra, bu yaklaşımın birden fazla kişiyi sildiğiniz ve bu silme işlemlerine ilişkin Ajax isteklerinin geri döndüğü durumu da kapsadığını unutmayın. Ajax çağrısı geri dönmeden önceki satır dizinlerini kullandıysanız, yanlış satırları kaldırırsınız.
Joris

4
Bazı durumlarda daha iyidir, ancak indexO ile doğru olanı bulmak için tüm öğeleri tekrarlamanız gerekiyorsa, Josh cevabında endeksi ve öğeyi daha hızlı elde edersiniz
daver

@mike - Bu çoklu dolguyu kullan .
Joseph Silber

8

Yararlı işlevlerin bir listesi olan Underscore.js kütüphanesini kullanırım .

without

without_.without(array, *values)

Tüm değerlerin kaldırıldığı dizinin bir kopyasını döndürür.

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

Misal

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'da Demo'ya bakın .


filter

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

// => [2, 4, 6]

Misal

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

Bkz. Fiddle'daki Demo .


Muhtemelen kullanmak istiyorum $scope.nodes = _.without($scope.nodes, node);diye referans var çünkünode
Jake

Modern tarayıcılarda kullanabilirsiniz Array.prototype.filter. _.filter(array, fun)olur array.filter(fun).
bfontaine

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

bu benim için çalışıyor!


4

Listeyle ilişkili herhangi bir işleviniz varsa, ekleme işlevini yaptığınızda ilişkilendirme de silinir. Çözümüm:

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

Liste parametresi, öğeler olarak adlandırılır . X.done parametresi , öğenin silinip silinmeyeceğini gösterir.

Başka referanslar: Başka bir örnek

Umarım yardımcı olurum. Selamlar.


2

@Joseph Silber'in kabul edilen cevabı çalışmıyor çünkü indexOf -1 döndürür. Muhtemelen Angular, $ scope.items [0] ve öğem için farklı olan bir hashkey ekliyor. Bunu angular.toJson () işleviyle çözmeye çalıştım, ancak işe yaramadı :(

Ah, sebebini buldum ... $ scope.items'imi izleyerek masamda iki sütun oluşturmak için yığın bir yöntem kullanıyorum. Afedersiniz!


2

Bunu da kullanabilirsiniz

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

1

Açısal yerleşik bir fonksiyona sahiptir arrayRemove, sizin durumunuzda yöntem basitçe şöyle olabilir:

arrayRemove($scope.persons, person)


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.