Wie kann ich eine $watch
Variable in einer Angular-Direktive auslösen, wenn ich die darin enthaltenen Daten bearbeite (z. B. Daten einfügen oder entfernen), dieser Variablen jedoch kein neues Objekt zuweisen?
Ich habe einen einfachen Datensatz, der gerade aus einer JSON-Datei geladen wird. Mein Angular-Controller erledigt dies und definiert einige Funktionen:
App.controller('AppCtrl', function AppCtrl($scope, JsonService) {
// load the initial data model
if (!$scope.data) {
JsonService.getData(function(data) {
$scope.data = data;
$scope.records = data.children.length;
});
} else {
console.log("I have data already... " + $scope.data);
}
// adds a resource to the 'data' object
$scope.add = function() {
$scope.data.children.push({ "name": "!Insert This!" });
};
// removes the resource from the 'data' object
$scope.remove = function(resource) {
console.log("I'm going to remove this!");
console.log(resource);
};
$scope.highlight = function() {
};
});
Ich habe eine <button>
, die die $scope.add
Funktion richtig aufgerufen hat , und das neue Objekt wird richtig in die $scope.data
Menge eingefügt . Eine von mir eingerichtete Tabelle wird jedes Mal aktualisiert, wenn ich auf die Schaltfläche "Hinzufügen" klicke.
<table class="table table-striped table-condensed">
<tbody>
<tr ng-repeat="child in data.children | filter:search | orderBy:'name'">
<td><input type="checkbox"></td>
<td>{{child.name}}</td>
<td><button class="btn btn-small" ng-click="remove(child)" ng-mouseover="highlight()"><i class="icon-remove-sign"></i> remove</button></td>
</tr>
</tbody>
</table>
Eine von mir eingerichtete Direktive $scope.data
wird jedoch nicht ausgelöst, wenn dies alles passiert.
Ich definiere mein Tag in HTML:
<d3-visualization val="data"></d3-visualization>
Was mit der folgenden Richtlinie verbunden ist (auf Fragen der Vernunft getrimmt):
App.directive('d3Visualization', function() {
return {
restrict: 'E',
scope: {
val: '='
},
link: function(scope, element, attrs) {
scope.$watch('val', function(newValue, oldValue) {
if (newValue)
console.log("I see a data change!");
});
}
}
});
Ich erhalte die "I see a data change!"
Nachricht ganz am Anfang, aber nie danach, wenn ich auf die Schaltfläche "Hinzufügen" klicke.
Wie kann ich das $watch
Ereignis auslösen , wenn ich nur Objekte zum data
Objekt hinzufüge / daraus entferne und dem Objekt kein ganz neues Dataset zuweisen data
kann?
quelle
if
Aussage vertauschen.Antworten:
Sie müssen die Prüfung auf Verschmutzung durch tiefe Objekte aktivieren. Standardmäßig überprüft Angular nur die Referenz der Variablen der obersten Ebene, die Sie beobachten.
siehe Geltungsbereich . Der dritte Parameter der $ watch-Funktion ermöglicht eine gründliche Überprüfung, ob er auf true gesetzt ist.
Beachten Sie, dass eine gründliche schmutzige Prüfung teuer ist . Wenn Sie also nur das untergeordnete Array anstelle der gesamten
data
Variablen überwachen müssen, überwachen Sie die Variable direkt.Version 1.2.x führte $ watchCollection ein
quelle
Denn wenn Sie Ihre Daten mit Deep of It auslösen möchten, müssen Sie das 3. Argument
true
Ihres Listeners übergeben. Standardmäßigfalse
wird Ihre Funktion nur dann ausgelöst, wenn sich Ihre Variable ändert, nicht das Feld .quelle
Meine Version für eine Direktive, die jqplot verwendet, um die Daten zu zeichnen, sobald sie verfügbar sind:
quelle