2016-11-16 114 views
0

我正在學習淘汰賽js,並已開始建立一個簡單的購物車。Knockout JS購物車練習

此購物車基本上要求用戶從下拉列表中選擇一個類別,然後第二個下拉列表中填充產品。

當用戶選擇一個產品時,顯示產品信息,即名稱/價格/數量/總數。 「添加項目」按鈕也是可見的。

數量數據是用戶可以增加數值的教科書。如果用戶遞增數量值,則總值將計算新的總數,即(價格*數量)。

當用戶點擊添加項目按鈕時,產品ID,姓名,數量和總數被存儲並顯示(除了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")); 

記得我是新來的淘汰賽JS。所以請原諒錯誤的編碼。謝謝

回答

0

這些問題似乎與您在添加項目後顯示數據時使用的值有關。如果我沒有錯,您將cart陣列內的屬性cartQty指定爲可觀察值。因爲您使用cart中的附加值只是爲了顯示標籤信息,並且用戶不應該更改該值(除非刪除該記錄然後在所需的修改後添加新記錄),則不需要使用雙向綁定,因此沒有必要指定觀察到的一樣,你在這裏做 -

var cartQty = quantity; 

因此,它始終是更好的分配只可觀察包圍的價值,而不是觀察的本身分離這些。

你可以嘗試這樣的事情 -

var cartQty = quantity(); 

因此,改變量沒有別處的副作用。

+0

謝謝,你的建議奏效。我將cartQty =數量更改爲cartQty = quantity()。爲了讓我更好地理解。如果我做了一個類似var a = b(b是可觀察的)的賦值,a基本上是b的一個副本,即a現在也是一個可觀察值。而如果我做了a = b(),a引用了b中包含的值。 – djslapdash

+0

賓果!你有它:)請接受這個答案,以便將來可能對其他人有所幫助。 – gkb