服务中的AngularJS数据触发计算函数
我有一个绑定到服务内数据的多步骤向导(wizardStateSvc)。我希望屏幕上有一个totals元素,每当影响总计的向导基值更新时,该元素都会更新。计算有点复杂(比我的示例中显示的要复杂),所以我希望在控制器中执行它。我想$watch可以解决这个问题,但现在发生的是$watch函数在初始化期间被调用一次,并且在我更新项目时从不触发。我怎样才能让这只$watch正确触发 总控制员:服务中的AngularJS数据触发计算函数,angularjs,angularjs-service,Angularjs,Angularjs Service,我有一个绑定到服务内数据的多步骤向导(wizardStateSvc)。我希望屏幕上有一个totals元素,每当影响总计的向导基值更新时,该元素都会更新。计算有点复杂(比我的示例中显示的要复杂),所以我希望在控制器中执行它。我想$watch可以解决这个问题,但现在发生的是$watch函数在初始化期间被调用一次,并且在我更新项目时从不触发。我怎样才能让这只$watch正确触发 总控制员: myApp.controller('wizardTotalsCtrl', ['wizardStateSvc',
myApp.controller('wizardTotalsCtrl', ['wizardStateSvc', '$scope', function (wizardStateSvc, $scope) {
$scope.products= wizardStateSvc.quote.products;
$scope.$watch(function() { return wizardStateSvc.quote.products; }, function(products) {
var total= 0;
products.forEach(function(product) {
total += product.price * (1 - (product.dealerDiscount * 0.01)) * product.quantity;
});
$scope.baseTotal = total;
});
}])
国家公务员:
myApp.service("wizardStateSvc", [function () {
var quote = {
products: [],
options: {},
customer: {},
shipping: {},
other: {}
}
return {
quote: quote
}
}]);
如果唯一可以更改的是
产品
数组的内容,即可以从数组中插入或删除产品,但其价格
不变,则使用$scope.$watchCollection
。代码与您的代码相同,只需将$watch
替换为$watchCollection
理由:$watch
检查是否相等;由于产品
阵列本身没有变化(即时间t1时的产品===时间t2时的产品
),因此手表永远不会触发。另一方面,$watchCollection
监视数组的内容,因此在本例中它就是您想要的
如果产品价格也可能发生变化,您需要更昂贵的
$scope.$watch(…,…,true)
。第3个参数处的true
表示深度监视,即遍历对象层次结构并检查每个嵌套属性。查看。您的手表观看阵列“产品”。初始化时,products是对数组的引用,添加值时,products仍然是对同一数组的引用,只是数组内容不同,因此您的手表没有理由再次调用该函数。此问题有两种解决方案:
不太好的解决方案:观察产品的长度,这会使手表在产品长度变化时被调用
$scope.$watch(function() { return wizardStateSvc.quote.products.length; }, ...);
在您添加一个项目,然后立即删除另一个项目的用例中,这是有问题的。如果在该操作之前,手表的值是x,那么在您的操作之后,手表的值将是x,因此不会调用
更好的解决方案:改用watch collection,它还处理监视长度所不能处理的用例
$scope.$watchCollection('products', ...);
从文档(滚动至$watchCollection部分):
$rootScope.Scope我需要深度手表,因为产品价格和分项折扣可能会发生变化。