【问题标题】:Binding failing with associative array in angularJSangularJS中的关联数组绑定失败
【发布时间】:2017-09-02 00:25:50
【问题描述】:

我正在尝试实现产品购物车行为,并且我有一个包含购物车 UI 元素的导航栏。服务 UserCart.js 处理产品添加/删除。该服务在 NavController 中使用,每次添加或删除产品时都会更新该服务。 Cart 元素中的所有 UI 绑定都可以正常工作,除了我绑定到包含购物车产品信息的关联数组的部分。它的key是Product ID,value是一个对象{Quantity:Z, CostPerUnit: Y}

UserCart.js

(function() {
// Get reference to the app
var app = angular.module("jargoViewer");

// Create the factory that share the User Cart with various controllers
app.factory('UserCart', function(){
    var cart_items = [];
    var cart = {
        cart_val: 0,
        cart_size : 0,
        cart_products : [],
        cart_prod_ids : []
    };

    var addProductInCart = function(prodID, prodCostPerUnit, prodQuantity) {
        console.log('BEFORE Came inside addProductInCart total_cart_val:'+cart.cart_val);
        console.log('Came inside addProductInCart prod:'+prodID + ', costPerUnit:'+prodCostPerUnit+',quantity:' + prodQuantity);
        if((prodID in cart_items)) {
            // true if "prodID" exist in cart_items
            // Add the new prodID key element now
            prodObj = cart_items[prodID];
            prodObj.Quantity = prodObj.Quantity + prodQuantity;
            // TODO DELETE
            cartProdObj = cart.cart_products[prodID];
            cartProdObj.Quantity = cartProdObj.Quantity + prodQuantity;
        } else {
            // A product with same key doesnt exists
            cart_items[prodID] = {
                'Quantity' : prodQuantity,
                'CostPerUnit' : prodCostPerUnit
            };
            // TODO DELETE
            cart.cart_products[prodID] = {
                'Quantity' : prodQuantity,
                'CostPerUnit' : prodCostPerUnit
            };
        }
        // Add the total newly added products cost to Total Cart Value
        cart.cart_val += prodCostPerUnit * prodQuantity;
        cart.cart_size += 1;
        cart.cart_prod_ids.push(prodID);

        console.log('AFTER Came inside addProductInCart total_cart_val:'+cart.cart_val);
    };

    var removeProductInCart = function(prodID, prodQuantity) {
        if((prodID in cart_items)) {
            // true if "prodID" exist in cart_items
            // Add the new prodID key element now
            prodObj = cart_items[prodID];
            existingQuantity = prodObj.Quantity;
            prodCostPerUnit = prodObj.CostPerUnit;
            if(prodQuantity > existingQuantity) {
               alert('No more of this item exists in the cart!');
            } else {
                prodObj.Quantity = prodObj.Quantity - prodQuantity;
                // Add the total newly added products cost to Total Cart Value
                cart.cart_val -= prodCostPerUnit * prodQuantity;
                cart.cart_size -= 1;
                // TODO DELETE
                cartProdObj = cart.cart_products[prodID];
                cartProdObj.Quantity = cartProdObj.Quantity - prodQuantity;
                if(prodObj.Quantity < 1) {
                    // No more of this product left in cart, remove from cart list
                    cart_items.splice(prodID, 1);
                    // TODO DELETE
                    cart.cart_products.splice(prodID, 1);
                    cart.cart_prod_ids.splice(prodID, 1);
                }
            }
        } else {
            // Error
            alert('No more of this item exists in the cart!');
        }
    };

    // Return the Interface of UserCart
    return { 
        products_in_cart: cart_items,
        cart : cart,
        addProdInCart : addProductInCart,
        delProdInCart : removeProductInCart
    };
});

}());

nav.html及其控制器NavController.js的代码如下:

(function() {

var app = angular.module("jargoViewer");

var NavController = function($scope, UserCart) {
    $scope.userCart = UserCart.cart;
    $scope.cart_products = UserCart.products_in_cart;
};

app.controller("NavController", NavController);

}());

nav.html

<!-- Navigation -->
    <nav id="mainNav" class="navbar navbar-default navbar-fixed-top navbar-custom">
        <div class="container" ng-controller = "NavController">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header page-scroll">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                    <span class="sr-only">Toggle navigation</span> Menu <i class="fa fa-bars"></i>
                </button>
                <a class="navbar-brand" href="#page-top">Jargo Foods</a>
            </div>

            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav navbar-right">
                    <li class="hidden">
                        <a href="#/main#page-top"></a>
                    </li>
                    <li class="page-scroll">
                        <a href="#/main#portfolio">Products</a>
                    </li>
                    <li class="page-scroll">
                        <a href="#/main#about">About</a>
                    </li>
                    <li class="page-scroll">
                        <a href="#/main#contact">Contact</a>
                    </li>
                    <!--
                    <li>                            
                        <p color:#fff>{{userCart.cart_val}} <i class="glyphicon glyphicon-shopping-cart" color:#fff></i></p>

                    </li>
                    -->
                    <li>
                        <div class="col-md-3">
                        <div id="cart" class="btn-group btn-block">
                            <button type="button" data-toggle="dropdown" class="btn btn-block btn-lg dropdown-toggle">
                                <i class="fa fa-shopping-cart"></i>
                                <span >Cart:</span> 
                                <span id="cart-total" ng-show ="userCart.cart_size">{{userCart.cart_size}} item(s) - ₹ {{userCart.cart_val}}</span>
                                <i class="fa fa-caret-down"></i>
                            </button>
                            <ul class="dropdown-menu pull-right">
                                <div >{{userCart.cart_products}}</div>
                                <div class="row" ng-repeat="(id, obj) in userCart.cart_products">{{id}} {{obj}}</div>
                                <div class="row" ng-repeat="obj in userCart.cart_prod_ids">{{obj}}</div>
                                <li>
                                    <table class="table table-striped hcart">
                                        <tbody>
                                            <tr ng-repeat="(id, itemObj) in cart_products">
                                                <td class="text-center">
                                                    <a href="product.html">
                                                        <img src="img/others/cart.png" alt="image" title="image" class="img-thumbnail img-responsive">
                                                    </a>
                                                </td>
                                                <td class="text-left">
                                                    <a href="product-full.html">
                                                        Seeds
                                                    </a>
                                                </td>
                                                <td class="text-right">x {{itemObj.Quantity}}</td>
                                                <td class="text-right">₹ {{itemObj.Quantity * itemObj.prodCostPerUnit}}</td>
                                                <td class="text-center">
                                                    <a href="#">
                                                        <i class="fa fa-times"></i>
                                                    </a>
                                                </td>
                                            </tr  >

                                    </tbody></table>
                                </li>
                                <li>
                                    <table class="table table-bordered total">
                                        <tbody>
                                            <tr>
                                                <td class="text-right"><strong>Sub-Total</strong></td>
                                                <td class="text-left">$1,101.00</td>
                                            </tr>
                                            <tr>
                                                <td class="text-right"><strong>Eco Tax (-2.00)</strong></td>
                                                <td class="text-left">$4.00</td>
                                            </tr>
                                            <tr>
                                                <td class="text-right"><strong>VAT (17.5%)</strong></td>
                                                <td class="text-left">$192.68</td>
                                            </tr>
                                            <tr>
                                                <td class="text-right"><strong>Total</strong></td>
                                                <td class="text-left">$1,297.68</td>
                                            </tr>
                                        </tbody>
                                    </table>
                                    <p class="text-right btn-block1">
                                        <a href="cart.html">
                                            View Cart
                                        </a>
                                        <a href="#">
                                            Checkout
                                        </a>
                                    </p>
                                </li>                                   
                            </ul>
                        </div>
                    </div>
                    </li>
                </ul>
            </div>
            <!-- /.navbar-collapse -->
        </div>
        <!-- /.container-fluid -->
    </nav>

每个绑定都可以正常工作,除了以下内容:

<div >{{userCart.cart_products}}</div>
<div class="row" ng-repeat="(id, obj) in userCart.cart_products">{{id}} {{obj}}</div>

请帮助找出问题所在。关联数组有什么特别需要做的吗?

【问题讨论】:

  • 您是否在控制台中遇到任何错误?
  • 你确定你是 NavController 控制了 DOM 的那部分吗?
  • userCart.cart_products 是一个对象数组,对吧?你可以试试obj in userCart.cart_products 吗?然后,在您的绑定中,您可以使用{{$index}} 而不是{{id}}。另外,我不确定 Angular 绑定如何呈现对象,我会尝试打印 obj 的实际属性,例如 obj.Quantity
  • @MattWebb 是的 NavController 处于控制之中,因为 nav.html 中的其他绑定正在工作
  • @crizzis cart_products 是一个关联数组。它的key是Product ID,value是一个对象{Quantity:Z, CostPerUnit: Y}

标签: javascript angularjs arrays


【解决方案1】:

您模板中的userCart.cart_products 不引用您的$scope 中的任何内容。

试试这个

var NavController = function($scope, UserCart) {
    $scope.userCart = UserCart.cart;
    $scope.userCart.cart_products = UserCart.products_in_cart;
};

您也可以简单地在 $scope 中公开UserCart

var NavController = function($scope, UserCart) {
    $scope.userCart = UserCart;
};

在你的模板中

<div >{{userCart.cart_products}}</div>
<div class="row" ng-repeat="(id, obj) in userCart.products_in_cart">{{id}} {{obj}}</div>

【讨论】:

  • 我在 nav.html 中有以下代码,它可以工作
    {{obj}}
    正如你可以注意到,UserCart.cart 对象既有 cart_prod_ids (这是一个购物车中的 prod id 的数组),也有 cart_products (这是一个关联数组,它的 key 是 Product ID,value 是一个对象 {Quantity:Z, CostPerUnit: Y }. 绑定适用于 cart_prod_ids 但不适用于 cart_products。
【解决方案2】:

好的,我找到了问题所在。作为 JS 的新手,我很难理解关联数组(或更准确地说是 JS 中的 MAP)是如何定义的。我所做的仍然是声明数组并尝试将其用作 MAP

    var cart = {
    cart_val: 0,
    cart_size : 0,
    cart_products : [],
    cart_prod_ids : []
};

这里有趣的部分是

cart_products : [],

这实际上声明了一个 ARRAY,而不是一个 MAP。要修复代码,我所要做的就是声明一个 MAP 而不是数组,所有其他代码保持不变!

cart_products : {},

这将 cart_products 声明为 MAP,然后以下将开始工作

<div class="row" ng-repeat="(id, obj) in userCart.cart_products">{{id}} {{obj}}</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多