Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
服务中的AngularJS数据触发计算函数_Angularjs_Angularjs Service - Fatal编程技术网

服务中的AngularJS数据触发计算函数

服务中的AngularJS数据触发计算函数,angularjs,angularjs-service,Angularjs,Angularjs Service,我有一个绑定到服务内数据的多步骤向导(wizardStateSvc)。我希望屏幕上有一个totals元素,每当影响总计的向导基值更新时,该元素都会更新。计算有点复杂(比我的示例中显示的要复杂),所以我希望在控制器中执行它。我想$watch可以解决这个问题,但现在发生的是$watch函数在初始化期间被调用一次,并且在我更新项目时从不触发。我怎样才能让这只$watch正确触发 总控制员: myApp.controller('wizardTotalsCtrl', ['wizardStateSvc',

我有一个绑定到服务内数据的多步骤向导(wizardStateSvc)。我希望屏幕上有一个totals元素,每当影响总计的向导基值更新时,该元素都会更新。计算有点复杂(比我的示例中显示的要复杂),所以我希望在控制器中执行它。我想$watch可以解决这个问题,但现在发生的是$watch函数在初始化期间被调用一次,并且在我更新项目时从不触发。我怎样才能让这只$watch正确触发

总控制员:

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

我需要深度手表,因为产品价格和分项折扣可能会发生变化。