我在我的控制器上使用了两个$watches
,它们应该关注这两个对象:
$scope.gastos = {
name: "Gastos mensuales",
data: [0,0,0,0,0,0,0,0,0,0,0,0],
labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
"Junio", "Julio", "Agosto", "Septiembre", "Octubre",
"Noviembre", "Diciembre"]
};
$scope.ganancias = {
name: "Ganancias mensuales",
data: [0,0,0,0,0,0,0,0,0,0,0,0],
labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
"Junio", "Julio", "Agosto", "Septiembre", "Octubre",
"Noviembre", "Diciembre"]
};
两个图表(来自Charts.js和angular-charts插件)从中读取数据。我已经将图表放在从属性接收数据的自定义指令中,并且它们正常工作。
问题是,我想创建另一个图表来读取与这些对象相同的另一个对象,但是在这个方法中计算它的数据:
function calcularBeneficios(){
var data = [];
for(var i=0;i<12;i++){
data[i] = $scope.ganancias.data[i] - $scope.gastos.data[i];
}
console.log("FUNCTION DATA: "+data);
return data;
}
这些是手表(我试过看object
和object.data
变量):
$scope.$watch("gastos", function(){
$scope.beneficios.data = calcularBeneficios();
console.log("SCOPE: "+$scope.beneficios.data);
});
$scope.$watch("ganancias", function(){
$scope.beneficios.data = calcularBeneficios();
console.log("SCOPE: "+$scope.beneficios.data);
});
这不起作用。你看到所有的console.logs
?我只看到"SCOPE" console.log
一次(ganancias
甚至不见两次)。当我更改绑定到这两个对象的某些输入中的数据时,一切正常(图表得到实时更新),但beneficios
图表没有,这些手表也没有工作。
我在这两块手表上做错了吗?
答案 0 :(得分:5)
问题是您正在观看顶级gastos
和ganancias
对象。这有两个潜在的问题:
正如docs for $watch所说,默认情况下,正常的JavaScript不等式用于确定对象是否已更改(x !== y
)。由于对象本身是同一个对象,您只是在中更改数据,这将始终为真,因此$watch
不会被触发。
您可以通过将objectEquality
标志设置为true($scope.$watch('x', function(){}, true)
)来解决问题。然后进行深入比较,并在data
数组中找出差异。然而,这更加注重性能。
由于您只是在每个对象中使用data
数组,因此您只需在gastos.data
上使用$scope.$watchCollection
即可。这更清洁,更快。
这是一个展示这个的工作片段:
angular.module("myApp", []).controller('myCtrl', function($scope) {
// same code
function calcularBeneficios() {
var data = [];
for (var i = 0; i < 12; i++) {
data[i] = $scope.ganancias.data[i] - $scope.gastos.data[i];
}
console.log("FUNCTION DATA: " + data);
return data;
}
$scope.beneficios = {
name: "Beneficios mensuales",
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
"Junio", "Julio", "Agosto", "Septiembre", "Octubre",
"Noviembre", "Diciembre"
]
};
$scope.gastos = {
name: "Gastos mensuales",
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
"Junio", "Julio", "Agosto", "Septiembre", "Octubre",
"Noviembre", "Diciembre"
]
};
$scope.ganancias = {
name: "Ganancias mensuales",
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
"Junio", "Julio", "Agosto", "Septiembre", "Octubre",
"Noviembre", "Diciembre"
]
};
// watch the array collection in gastos.data
$scope.$watchCollection("gastos.data", function() {
$scope.beneficios.data = calcularBeneficios();
console.log("SCOPE: " + $scope.beneficios.data);
});
// watch the array collection in ganancias.data
$scope.$watchCollection("ganancias.data", function() {
$scope.beneficios.data = calcularBeneficios();
console.log("SCOPE: " + $scope.beneficios.data);
});
// testing functions
$scope.changeGastos = function() {
$scope.gastos.data[4] = 10;
}
$scope.changeGanancias = function() {
$scope.ganancias.data[0] = 40;
}
})
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<h3>beneficios.data</h3>
<ul>
<li ng-repeat="i in beneficios.data track by $index">{{i}}</li>
</ul>
<button ng-click="changeGastos()">Change Gastos</button>
<button ng-click="changeGanancias()">Change Ganancias</button>
</div>
&#13;
答案 1 :(得分:3)
使用$watchCollection代替$watch
来观看收藏。
或者你也可以这样看:
$scope.$watch("gastos + ganancias", function(){
$scope.beneficios.data = calcularBeneficios();
console.log("SCOPE: "+$scope.beneficios.data);
});