angular scoped variable in controller not updating

2019-08-02 07:48发布

问题:

I'm developing a mini-basket in angular for an ecommerce application but have a problem with a scoped variable not updating via a service.

When i click on an add to basket button in the product grid it fires the upDateMiniBasket function in the product grid controller which has the UpdateMiniBasket service injected into it.

The controller:

whiskyControllers.controller('whiskyListCtrlr', ['$scope', 'UpdateMiniBasket', '$http', 

    function($scope, UpdateMiniBasket, $http){
        $http.get('json/whiskies.json').success(function(data){
            $scope.whiskies = data;
        })

        $scope.updateMiniBasket = function(e){
            var targetObj = e.target.getAttribute('data-item');

            UpdateMiniBasket.getUpdate(targetObj);

        }
    }

])

Here is the service:

whiskyrumApp.factory('UpdateMiniBasket', [function(){

    var miniBasketTotal = 0, 
        itemCount = 0;

    var miniBasketItems = [{
        imageUrl : '',
        name : 'There are currently no items in your basket',
        price: 0
    }]

    var getUpdate = function(obj){

        miniBasketTotal = 0;

        if(obj) {
            if(miniBasketItems[0].price === 0) miniBasketItems.pop();
            obj = jQuery.parseJSON(obj);
            miniBasketItems.push(obj);
        }

        for(var i = 0, j = miniBasketItems.length; i < j; i++){
            miniBasketTotal += parseFloat(miniBasketItems[i].price);
        }

        itemCount = miniBasketItems[0].price === 0 ? 0 : miniBasketItems.length;

        return {
            miniBasketItems : miniBasketItems,
            miniBasketTotal : miniBasketTotal,
            itemCount : itemCount
        }
    }

    return {
        getUpdate : getUpdate
    }

}]);

The problem is that when I add a product, the function fires and calls the service ok, but a scoped variable that should update the amount of items in the basket is not updating. This variable lives in another controller for the minibasket that also has teh UpdateMiniBasket service injected.

whiskyControllers.controller('miniBasketCtrlr', ['$scope', 'UpdateMiniBasket',

    function($scope, UpdateMiniBasket){

        var mbItems = UpdateMiniBasket.getUpdate();

        $scope.miniBasketItems = mbItems.miniBasketItems;
        $scope.itemCount = mbItems.itemCount;

}])

And this is html:

<div class="mini-basket grey-box" ng-controller="miniBasketCtrlr">

    <a href="#" data-toggle="dropdown" class="btn dropdown-toggle">
        {{itemCount}} Items
    </a>
   <!-- the ng-repeat code for the mini basket which works fine -->

I just assumed that when the variables in the service are updated, that would feed through to the scoped var in the other controller as they are both linked to the same service. I thought maybe I need to add a $watch as I cant see why this {{itemCount}} is not updating. Any help would be greatly appreciated.

回答1:

If you change the return object of your UpdateMiniBasket factory to instead of returning the primitive value for the count of items but to a function like below:

return {
    miniBasketItems : miniBasketItems,
    miniBasketTotal : miniBasketTotal,
    itemCount : function () {
        return itemCount;
    }
}

And then in your controller change the binding to $scope to this:

$scope.itemCount = function () {
    return mbItems.itemCount(); 
};

You should then just have to change the binding in the html to {{ itemCount() }} and this value should then successfully update when the values in the factory update.

I have a simplified solution to this on jsbin here: http://jsbin.com/guxexowedi/2/edit?html,js,output