淘汰JS购物车运动

时间:2016-11-16 11:20:41

标签: javascript jquery asp.net-mvc mvvm knockout.js

我正在学习淘汰赛,并开始构建一个简单的购物车。

此购物车基本上要求用户从下拉列表中选择一个类别,然后在第二个下拉列表中填充产品。

当用户选择产品时,显示产品信息,即名称/价格/数量/总数。一个'添加项目'按钮也可见。

数据数据是教科书,用户可以在其中增加值。如果用户递增数量值,则总值将计算新总数,即(价格*数量)。

当用户点击添加项目按钮时,产品ID,名称,数量和总数被存储并显示在相邻的div即购物车列表中(除了id)。

我遇到的问题是,当商品位于购物车中时,数量为1,而我想将新商品添加到数量为2的购物车中。购物车中的数量值也会更改为2。值应保持为1,购物车中的总值也与新项目的值相匹配。

这是代码:

<div id="exp2">
    <div>
        <span>
            <select id="ddlCat" data-bind="options: lstCategories, optionsText: 'name',
            optionsValue: 'id', optionsCaption: 'Select Category...',
            value: selectedCate"></select>
        </span>
        <span data-bind="visible: lstProducts().length > 0">
            <select id="ddlProd" data-bind="options: lstProducts, optionsText: 'name',
            optionsValue: 'id',  optionsCaption: 'Select Product...',
            value: selectedProdId"></select>
        </span>
        <span data-bind="with: selectedProd()">
            Price: £<span id="pPrice" data-bind="text: price"></span>, &nbsp;
            Qty <input type="text" id="pQty" data-bind="value: quantity" style="width:30px;"
                       placeholder="" required />
            SubTotal: £<span data-bind="text: itemTotal()"></span>
            <span><button id="btnAdd" class="btnAdd" data-bind="click: addItem">Add to cart</button></span>
        </span>
    </div>
    <div>
        <h3>Items In Cart</h3>
        <ul id="lstCart" data-bind="foreach: cart">
            <li>
                Name: <span data-bind="text: name"></span>&nbsp;
                Qty: <span data-bind="text: qty"></span>&nbsp;
                Item Total: £<span data-bind="text: itemTotal"></span>&nbsp;
            </li>
        </ul>
        Sub Total: £<span data-bind="text: subTotal()"></span>
    </div>
  </div>

的Javascript

        var categories = [];
        var products = [];
        var cartLines = [];

        $.ajax({
            url: '../KnockoutTut/page5GetCat',
            type: "GET", cache: false, async: false,
            contentType: "application/json; charset=utf-8",
            dataType: "json", traditional: true,
            success: function (data) {
                //alert('Process Successful');
                for (var i = 0; i < data.length; i++) {
                    var id = data[i].id; var name = data[i].name;
                    //var nCat = new Category(id, name);
                    categories.push( new Category(id,name));
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                //alert("Error")
                alert(jqXHR.status + "," + jqXHR.responseText + "," + errorThrown);
            }
        });

        function getProd(catId) {
            products = [];
            var value = { 'value': catId };
            var json = JSON.stringify(value);
            $.ajax({
                url: '../KnockoutTut/page5GetProd',
                type: "POST", data: json, cache: false, async: false,
                contentType: "application/json; charset=utf-8",
                dataType: "json", traditional: true,
                success: function (data) {
                    //alert('Process Successful');
                    for (var i = 0; i < data.length; i++) {
                        var id = data[i].id; var name = data[i].name;
                        var price = data[i].price; var qty = data[i].qty;
                        products.push(new Product(id, name, price, 1));
                    }
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    //alert("Error")
                    alert(jqXHR.status + "," + jqXHR.responseText + "," + errorThrown);
                }
            });
        }

        function Category(id, name) {
            this.id = id;
            this.name = name;
        };

        function Item(id, name, qty, itemTotal) {
            this.id = id;
            this.name = name;
            this.qty = qty;
            this.itemTotal = itemTotal;
        };

        function Product(id, name, price, qty) {
            this.id = id;
            this.name = name;
            this.price = price;
            this.qty = qty;
        };

        function viewModel() {

            var self = this;
            self.lstCategories = ko.observableArray(categories);
            self.lstProducts = ko.observableArray([]);
            self.cart = ko.observableArray([]);
            self.selectedCate = ko.observable();
            self.selectedProdId = ko.observable();
            self.selectedProd = ko.observable();
            self.quantity = ko.observable(1);
            self.catQty = ko.observable();

            self.itemTotal = ko.pureComputed(function () {
                return self.selectedProd() ? self.selectedProd().price * parseInt("0" + self.quantity(), 10) : 0;
            });

            self.subTotal = ko.pureComputed(function () {
                var total = 0;
                $.each(self.cart(), function () { total += this.itemTotal() })
                return total;
            });

            self.selectedCate.subscribe(function (pCatId) {
                var catId = pCatId;
                if ($.isNumeric(catId)) {
                    getProd(catId);
                }
                self.lstProducts(products);
            });

            self.selectedProdId.subscribe(function (pProdId) {
                var pId = pProdId;
                var match = ko.utils.arrayFirst(lstProducts(), function (item) {
                    return pId === item.id;
                });
                self.selectedProd(match);
                //alert(selectedProd().qty);
            });

            self.addItem = function (item) {
                var nId = item.id; var nName = item.name; var cartQty = quantity; var iTot = itemTotal;
                cart.push(new Item(nId, nName, cartQty, iTot));
                //cart.push(cartLines);
            };                
        };
        ko.applyBindings(viewModel, document.getElementById("exp2"));

记住我是淘汰赛的新手。所以请原谅糟糕的编码。感谢

1 个答案:

答案 0 :(得分:0)

问题似乎与您在添加项目后显示数据的价值有关。如果我没有错,那么您正在为cartQty数组内的属性cart分配observable。因为,您使用cart中的添加值只是为了显示标签信息而用户不应该更改它(当然除非删除该记录然后在所需修改后添加新记录),所以不需要使用双向绑定,因此不需要像在这里那样分配observable -

var cartQty = quantity;

因此,最好通过仅分配observable包含的值而不是observable本身来分隔它们。

你可以尝试这样的事情 -

var cartQty = quantity();

因此,改变数量不会在其他地方产生副作用。