it-swarm.com.de

So beobachten Sie ein Array auf Änderungen in AngularJS

Im Grunde möchte ich das Äquivalent des Bindens zum Hinzufügen und Entfernen von Ereignissen in den Backbone-Sammlungen. Ich sehe im Prinzip keine Möglichkeit, dies in AngularJS zu tun, und die aktuelle Problemumgehung, für die wir uns entschieden haben, ist $watch()ing der length des Arrays und die manuelle Differenzierung/Neuberechnung der gesamten Sache. Ist es wirklich das, was die coolen Kinder tun?

Edit : Insbesondere wenn Sie die Länge des Arrays betrachten, weiß ich nicht so leicht, welches Element geändert wurde. Ich muss manuell "diff".

28
abyx

Ich denke mit $watch ist eine gute Lösung, aber $watchCollection kann für Sie besser sein. $watchCollection führt keinen tiefen Vergleich durch und achtet nur auf Array-Änderungen wie Einfügen, Löschen oder Sortieren (keine Elementaktualisierung).

Wenn Sie zum Beispiel ein Attribut order mit der Array-Reihenfolge synchronisieren möchten:

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

Aber für Ihr Problem weiß ich nicht, ob es eine bessere Lösung gibt, als das Array manuell zu durchsuchen, um die Änderung zu identifizieren.

31
Noémi Salaün

Ein Array in Angular kann mit $watch(array, function(){} ,true) betrachtet werden.

12
Jason Als

Ich würde untergeordnete Bereiche erstellen und einzeln betrachten. Hier ein Beispiel:

$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

Bitte erzählen Sie mehr über Ihre Verwendung. Eine der Lösungen für die Verfolgung von Elementelementen besteht in der Verwendung der Anweisung ngRepeat mit der benutzerdefinierten Anweisung des $ destroy-Ereignisses des Listenelements: 

<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

Vielleicht besteht die Lösung darin, die Collection-Klasse zu erstellen (wie Backbone dies tut), und Sie können sich auch ganz einfach in Ereignisse einbinden. 

Die Lösung, die ich hier gemacht habe, ist nicht wirklich umfassend, sollte aber eine allgemeine Anleitung dazu geben, wie dies vielleicht getan werden könnte. 

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

0
ganaraj