javascript - directivas - limitto angular 6
$ watch''ing para cambios de datos en una directiva Angular (3)
¿Cómo puedo disparar una variable $watch
en una directiva angular cuando manipulo los datos dentro (por ejemplo, insertar o eliminar datos), pero no asignar un nuevo objeto a esa variable?
Tengo un conjunto de datos simple que se está cargando actualmente desde un archivo JSON. Mi controlador Angular hace esto, así como también define algunas funciones:
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() {
};
});
Tengo un <button>
que correctamente llamó a la función $scope.add
, y el nuevo objeto se inserta correctamente en el conjunto $scope.data
. Una tabla que configuré se actualiza cada vez que presiono el botón "agregar".
<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>
Sin embargo, una directiva que configuré para ver $scope.data
no se $scope.data
cuando ocurre todo esto.
Defino mi etiqueta en HTML:
<d3-visualization val="data"></d3-visualization>
Que está asociado con la siguiente directiva (recortada para la cordura de la pregunta):
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!");
});
}
}
});
Obtengo el mensaje "I see a data change!"
mensaje al principio, pero nunca después cuando presiono el botón "agregar".
¿Cómo puedo activar el evento $watch
cuando solo agrego / elimino objetos del objeto de data
, sin obtener un nuevo conjunto de datos para asignar al objeto de data
?
Debe habilitar la comprobación sucia de objetos profundos. De forma predeterminada, angular solo verifica la referencia de la variable de nivel superior que observa.
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!");
}, true);
}
}
});
ver Scope . El tercer parámetro de la función $ watch permite una verificación profunda y sucia si se establece en verdadero.
Tenga en cuenta que la verificación profunda y sucia es costosa . Por lo tanto, si solo necesita ver la matriz de elementos secundarios en lugar de toda data
variable de data
, mire directamente la variable.
scope.$watch(''val.children'', function(newValue, oldValue) {}, true);
la versión 1.2.x presentó $watchCollection
Shallow observa las propiedades de un objeto y dispara cada vez que cambia alguna de las propiedades (para las matrices, esto implica observar los elementos de la matriz; para los mapas de objetos, esto implica observar las propiedades)
scope.$watchCollection(''val.children'', function(newValue, oldValue) {});
Mi versión para una directiva que usa jqplot para trazar los datos una vez que estén disponibles:
app.directive(''lineChart'', function() {
$.jqplot.config.enablePlugins = true;
return function(scope, element, attrs) {
scope.$watch(attrs.lineChart, function(newValue, oldValue) {
if (newValue) {
// alert(scope.$eval(attrs.lineChart));
var plot = $.jqplot(element[0].id, scope.$eval(attrs.lineChart), scope.$eval(attrs.options));
}
});
}
});
Porque si quieres desencadenar tus datos con profundidad, tienes que pasar el tercer argumento true
de tu oyente. Por defecto es false
y significa que tu función se disparará, solo cuando tu variable cambie, no su campo .