自定义角度指令控制器未更新

时间:2016-04-14 22:18:10

标签: angularjs angularjs-scope angular-directive angular-controller

我创建了自己的angular指令,可以简单地用作:

<basket-summary></basket-summary>

此元素用于我的主模板页面(index.html)。

该指令如下:

/* Directive */
angular.module('ecommerceDirectives').directive('basketSummary', [function() {
    return {
        restrict : 'E',
        scope: {},
        replace: true,
        controller : 'BasketController',
        controllerAs: 'basketController',
        bindToController: {
            basketController : '='
        },
        templateUrl: function(element, attrs) {
            if (typeof attrs.templateUrl == 'undefined') {
                return 'app/views/basket-summary.html';
            } else {
                return attrs.templateUrl;
            }
        },
        link: function (scope, element, attrs) {
            console.log("test");
        }
    };
}]);

此指令的templateUrl如下:

<div class="btn-group pull-right"> 
    <a class="btn btn-warning" ng-click="basketController.viewBasket()"><span class="badge">{{basketController.getTotalQuantities()}}</span> <span class="hidden-xs">Shopping</span> Cart</a>
    <button type="button" class="btn btn-warning dropdown-toggle" data-toggle="dropdown">
        <span class="fa fa-caret-down"></span>
        <span class="sr-only">Toggle Dropdown</span>
    </button>

    <div class="dropdown-menu">
        <div class="col-xs-12 cartItemHeader">
            <h4>My Shopping Cart</h4>
        </div>

        <div class="quickCart" ng-repeat="cartItem in basketController.customerBasket.items">
            <div class="col-xs-12 cartItemWrap">
                <div class="col-xs-12 desc"><a href="">{{cartItem.product.title}}</a></div>
                <div class="col-xs-5 col-sm-8 price">{{cartItem.product.rrp_currency}} {{cartItem.product.rrp_amount}}</div>
                <div class="col-xs-6 col-sm-3 units">Items: {{cartItem.quantity}}</div>
                <div class="col-xs-1 trash"><a ng-click="basketController.deleteCartItem(cartItem.product.id)"><i class="fa fa-trash"></i></a></div>
           </div>
       </div>
   </div>

BasketController如下:

/* Controller */
angular.module('ecommerceControllers').controller('BasketController', ['$rootScope', '$scope', '$route', '$location', 'CustomerBasketService', 'AppSettingService', 'StorageService', 'DEFAULT_CURRENCY_CODE', 'MERCHANT_ID_KEY', function($rootScope, $scope, $route, $location, CustomerBasketService, AppSettingService, StorageService, DEFAULT_CURRENCY_CODE, MERCHANT_ID_KEY) {

    function basketProduct(product) {
        this.id = product.id;
        this.title = product.title;
        this.categories = product.categories;
        this.images = product.imaes;
        this.created_on = product.created_on;
        this.sku_code = product.sku_code;
        this.lang = product.lang;
        this.short_description = product.short_description;
        this.attributes = product.attributes;
        this.rrp_currency = product.rrp_currency;
        this.rrp_amount = product.rrp_amount;
        this.barcode_number = product.barcode_number;
        this.last_modified_on = product.last_modified_on;
    }

    function basketItem(quantity, product) {
        this.quantity = quantity;
        this.product = new basketProduct(product);
    }

    function load() {
        var basket = StorageService.get("customer_basket");
        if (basket) {
            for (var i = 0; i < basket.items.length; i++) {
                var cartItem = basket.items[i];
                cartItem = new basketItem(cartItem.quantity, cartItem.product);
                basket.items[i] = cartItem;
            }
        }

        return basket;
    }

    var basketController = this;
    $scope.basketController = basketController;
    basketController.customerBasket = load();

    if (!basketController.customerBasket) {
        basketController.customerBasket = {
            shipping : null,
            taxRate : null,
            tax : null,
            items : []
        };
    }

    basketController.addCartItem = function(quantity, product) {
        if (product == undefined || product == null) {
            throw "No Product was specified.";
        }

        if (quantity == undefined || quantity == null) {
            quantity = null;
        }

        var found = false;
        if (basketController.customerBasket && basketController.customerBasket.items && basketController.customerBasket.items.length > 0) {
            for (var i = 0; i < basketController.customerBasket.items.length; i++) {
                var cartItem = basketController.customerBasket.items[i];
                if (product.id === cartItem.product.id) {
                    found = true;
                    cartItem.quantity = cartItem.quantity + quantity;
                    if (cartItem.quantity < 1) {
                        basketController.customerBasket.items.splice(i, 1);
                    } else {
                        $rootScope.$broadcast('customerBasketItemUpdated', {item: cartItem});
                    }
                }
            }
        }

        if (!found) {
            var cartItem = new basketItem(quantity, product);
            basketController.customerBasket.items.push(cartItem);
            $rootScope.$broadcast('customerBasketItemAdded', {item: cartItem});
        }

        basketController.saveBasket();
    }

    basketController.updateBasket = function() {
        if (basketController.customerBasket && basketController.customerBasket.items && basketController.customerBasket.items.length > 0) {
            for (var i = 0; i < basketController.customerBasket.items.length; i++) {
                var cartItem = basketController.customerBasket.items[i];
                if (cartItem.quantity < 1) {
                    basketController.customerBasket.items.splice(i, 1);
                }
            }
        }

        basketController.saveBasket();
    }

    basketController.deleteCartItem = function(productId) {
        if (productId == undefined) {
            throw "Product ID is required.";
        }

        if (basketController.customerBasket && basketController.customerBasket.items && basketController.customerBasket.items.length > 0) {
            for (var i = 0; i < basketController.customerBasket.items.length; i++) {
                var cartItem = basketController.customerBasket.items[i];
                if (productId == cartItem.product.id) {
                    basketController.customerBasket.items.splice(i, 1);
                }
            }
        }

        //Save
        basketController.saveBasket();
    }

    basketController.getCurrencyCode = function() {
        var code = DEFAULT_CURRENCY_CODE;

        if (basketController.customerBasket && basketController.customerBasket.items && basketController.customerBasket.items.length > 0) {
            code = basketController.customerBasket.items[0].product.rrp_currency;
        }

        return code;
    };

    basketController.getTotalQuantities = function(id) {
        var total = 0;
        if (basketController.customerBasket && basketController.customerBasket.items && basketController.customerBasket.items.length > 0) {
            for (var i = 0; i < basketController.customerBasket.items.length; i++) {
                var cartItem = basketController.customerBasket.items[i];
                if (id == undefined || id == cartItem.product.id) {
                    total += cartItem.quantity;
                }
            }
        }

        return total;
    };

    basketController.getTotalAmount = function(cartItem) {
        var total = 0;
        if (cartItem) {
            total = (cartItem.quantity * cartItem.product.rrp_amount);
        }

        return total.toFixed(2);
    };

    basketController.getFinalTotalAmount = function() {
        var total = 0;
        if (basketController.customerBasket && basketController.customerBasket.items && basketController.customerBasket.items.length > 0) {
            for (var i = 0; i < basketController.customerBasket.items.length; i++) {
                var cartItem = basketController.customerBasket.items[i];
                total += (cartItem.quantity * cartItem.product.rrp_amount);
            }
        }

        return total.toFixed(2);
    };

    basketController.clearBasket = function() {
        StorageService.set("customer_basket", null);
        basketController.customerBasket = {
            shipping : null,
            taxRate : null,
            tax : null,
            items : []
        };

        $rootScope.$broadcast('customerBasketCleared', {});
    }

    basketController.saveBasket = function() {
        if (basketController.customerBasket) {
            StorageService.set("customer_basket", basketController.customerBasket);
            $rootScope.$broadcast('customerBasketSaved', {});
        }
    }

    basketController.checkout = function(serviceName, clearCart) {
        if (serviceName == undefined || serviceName == null) {
            serviceName = "PayPal";
        }

        switch (serviceName) {
            case "PayPal":
                basketController.checkoutPayPal(clearCart);
            break;
            default:
                throw "Unknown checkout service '" + serviceName + "'.";
        }
    };

    basketController.checkoutPayPal = function(clearCart) {
        if (basketController.customerBasket && basketController.customerBasket.items && basketController.customerBasket.items.length > 0) {

            // global data
            var data = {
                cmd: "_cart",
                business: '', //parms.merchantID,
                upload: "1",
                rm: "2",
                charset: "utf-8"
            };

            AppSettingService.getAppSetting(MERCHANT_ID_KEY).get().$promise
            .then(function(result) {
                data.business = result.value;

                for (var i = 0; i < basketController.customerBasket.items.length; i++) {
                    var cartItem = basketController.customerBasket.items[i];

                    var ctr = i + 1;
                    data["item_number_" + ctr] = cartItem.product.sku_code;
                    data["item_name_" + ctr] = cartItem.product.title;
                    data["quantity_" + ctr] = cartItem.quantity;
                    data["amount_" + ctr] = cartItem.product.rrp_amount.toFixed(2);
                }

                // build form
                var form = $('<form/></form>');
                form.attr("action", "https://www.paypal.com/cgi-bin/webscr");
                form.attr("method", "POST");
                form.attr("style", "display:none;");
                addFormFields(form, data);
                $("body").append(form);

                // submit form
                form.submit();
                form.remove();

                if (clearCart) {
                    try {
                        basketController.clearBasket();
                    } catch (exception) {

                    }
                }
            }).catch(function(reason) {
                console.log(reason);
            });
        }
    };

    basketController.viewBasket = function() {
        $location.path("/basket");
        $route.reload();
    };

    function addFormFields(form, data) {
        if (data != null) {
            $.each(data, function (name, value) {
                if (value != null) {
                    var input = $("<input></input>").attr("type", "hidden").attr("name", name).val(value);
                    form.append(input);
                }
            });
        }
    }

    return basketController;
}]);

我的困境如下:

在我的产品页面上,我有product.html页面(这是一个有角度的视图),“添加到购物车”按钮会将项目添加到购物车,但它不会更新我的购物车摘要按钮。

如何点击“添加到购物车”按钮更新我的购物车以及添加到购物车的商品数量?

示例图片:

enter image description here

正如您所见,右上角的橙色按钮表示我没有任何物品,但我的购物车中有3件物品。

我尝试了指令中允许的各种范围,但我似乎无法使其工作。

PS:我是AngularJS的新手,所以请简单易懂。 : - )

视图product.html已链接到BasketController,这是将商品添加到购物车的按钮。

<a class="btn btn-success btn-lg pull-right" role="button" ng-click="basketController.addCartItem(1, productController.selectedProduct)"><i class="fa fa-plus"></i> Add To Cart</a></div>

1 个答案:

答案 0 :(得分:1)

您有一个孤立的范围问题。指令的控制器与您要在产品页面中使用的控制器不同。请参阅:scopes

我建议你创建一个工厂,它总是一个单独存储您的篮子产品并将它们注入指令和产品页面