web-dev-qa-db-fra.com

Comment regarder un tableau pour les changements dans AngularJS

Je veux fondamentalement l'équivalent de lier pour ajouter des événements 'et' supprimer 'dans les collections de Backbone. Je ne vois fondamentalement aucun moyen de faire cela dans AngularJS, et la solution de contournement actuelle que nous avons choisie est $watch()ing la variable length du tableau et la différenciation/recalculation manuelle du tout. Est-ce vraiment ce que font les enfants cools?

Edit : Plus précisément, regarder la longueur du tableau signifie que je ne sais pas facilement quel élément a été modifié, je dois manuellement "diff".

28
abyx

Je pense que l’utilisation de $watch est une bonne solution, mais $watchCollection peut être préférable pour vous. $watchCollection n'effectue pas de comparaison approfondie et se contente de regarder pour modifier un tableau, comme insérer, supprimer ou trier (not item update).

Par exemple, si vous souhaitez conserver une attribut order synchroniser avec l'ordre du tableau:

$scope.sortableItems = [
    {order: 1, text: 'foo'},
    {order: 2, text: 'bar'},
    {order: 3, text: 'baz'}
];

$scope.$watchCollection('sortableItems', function(newCol, oldCol, scope) {
    for (var index in newCol) {
        var item = newCol[index];
        item.order = parseInt(index) + 1;
    }
});

Mais pour votre problème, je ne sais pas s'il existe une meilleure solution que de parcourir manuellement le tableau pour identifier le changement.

31
Noémi Salaün

La manière de regarder un tableau dans Angular est $watch(array, function(){} ,true)

12
Jason Als

Je créerais des lunettes de vue pour enfants et les regarderais individuellement. Voici un exemple:

$scope.myCollection = [];
var addChild = function()
{
  var Child = $scope.$new();
  Child.name = 'Your Name here';

  Child.$watch('name', function(newValue) {
     // .... do something when the attribute 'name' is changed ...
  });

  Child.$on('$destroy', function() {
    //... do something when this child gets destroyed 
  });


  $scope.myCollection.Push(Child); // add the child to collection array

};

// Pass the item to this method as parameter, 
// do it within an ngRepeat of the collection in your views 
$scope.deleteButtonClicked = function(item)
{
  var index = $scope.myCollection.indexOf(item); //gets the item index
  delete $scope.myCollection[index]; // removes the item on the array
  item.$destroy(); // destroys the original items
}
3
Raftalks

Veuillez en dire plus sur votre cas d'utilisation. Une des solutions de suivi de la persistance des éléments consiste à utiliser la directive ngRepeat avec la directive personnalisée de l'événement $ destroy de l'élément à l'écoute: 

<div ng-repeat="item in items" on-delete="doSomething(item)">

angular.module("app").directive("onDelete", function() {
    return {
        link: function (scope, element, attrs) {
            element.on("$destroy", function () {
                scope.$eval(attrs.onDelete);
            });
        }
    }
});
0
ardentum-c

Peut-être que la solution consiste à créer la classe collection (comme le fait Backbone) et vous pouvez également vous connecter facilement à des événements. 

La solution que j’ai proposée ici n’est pas vraiment complète, mais devrait vous donner des indications générales sur la manière de procéder. 

http://beta.plnkr.co/edit/dGJFDhf9p5KJqeUfcTys?p=preview

0
ganaraj