简体   繁体   English

我的样本购物车无法正常工作

[英]My sample shopping cart is not working as expected knockout js

I am learning knockout.js. 我正在学习knockout.js。 So I'm try to build a sample cart where initially a drop down will come with product data. 因此,我尝试构建一个样本购物车,最初会在其中附带产品数据。 When user select any product then corresponding price and quantity will be filled up in right input control and sub total will be calculated automatically by computed property. 当用户选择任何产品时,将在正确的输入控件中填写相应的价格和数量,并通过计算的属性自动计算小计。

Initially when I run my program then one data is showing for a cart but when I select any product then price and Qty value is not getting filled up and no sub total is showing. 最初,当我运行程序时,将显示一个购物车的数据,但是当我选择任何产品时,价格和数量值都不会被填满,也没有小计。 I am new in KO and that why some where I made the silly mistake which is not getting clear before my eyes. 我是KO的新手,那为什么为什么我犯了一个愚蠢的错误,而这个错误却在我眼前变得不明显。 So please guide me where I made the mistake. 所以,请指导我哪里出错了。

Here is my full code 这是我的完整代码

 <table id="table1" cellspacing="0" cellpadding="0" border="0">
    <tr>
        <th style="width:150px">Product</th>
        <th>Price ($)</th>
        <th>Quantity</th>
        <th>Amount ($)</th>
    </tr>

    <tbody data-bind='template: {name: "orderTemplate", foreach: lines}'></tbody>
</table>

<script type="text/html" id="orderTemplate">
    <tr>
        <td><select data-bind="options: products, 
                               optionsText: 'name', 
                               value: id,
                               optionsCaption:'--Select--'">,
                               value: $parent.product
                               </select>
        </td>
        <td><span data-bind="value: price" /></td>
        <td><input data-bind="value: quantity" /></td>
        <td><span data-bind="value: subtotal" /></td>
    </tr>
</script>

<script type="text/javascript">
    var _products = [
      {
          "name": "1948 Porsche 356-A Roadster",
          "price": 53.9
          , quantity: 1
      },
      {
          "name": "1948 Porsche Type 356 Roadster",
          "price": 62.16
          , quantity: 1
      },
      {
          "name": "1949 Jaguar XK 120",
          "price": 47.25
          , quantity: 1
      },
      {
          "name": "1952 Alpine Renault 1300",
          "price": 98.58
          , quantity: 1
      },
      {
          "name": "1952 Citroen-15CV",
          "price": 72.82
          , quantity: 1
      },
      {
          "name": "1956 Porsche 356A Coupe",
          "price": 98.3
          , quantity: 1
      },
      {
          "name": "1957 Corvette Convertible",
          "price": 69.93
          , quantity: 1
      }];

    function formatCurrency(value) {
        return "$" + value.toFixed(2);
    }

    var CartLine = function () {
        var self = this;
        self.products = ko.observableArray(_products);
        self.product = ko.observable();
        self.quantity = ko.observable(1);
        self.price = ko.observable(1);
        self.subtotal = ko.computed(function () {
            return self.product() ? self.product().price * parseInt("0" + self.quantity(), 10) : 0;
        });

    };

    var Cart = function () {
        // Stores an array of lines, and from these, can work out the grandTotal
        var self = this;
        self.lines = ko.observableArray([new CartLine()]); // Put one line in by default
    };

    ko.applyBindings(new Cart());    
</script>

So there's a few issues here. 所以这里有一些问题。 First of all, your binding for the dropdown is malformed 首先,您对下拉列表的绑定格式不正确

<select data-bind="options: products, 
                           optionsText: 'name', 
                           value: id,
                           optionsCaption:'--Select--'">,
                           value: $parent.product
                           </select>

The Value field is declared inside the data-bind to the property 'id' which I don't see in the view model. 值字段在数据绑定内声明为属性“ id”,而在视图模型中看不到该属性。 The value binding outside ('value: $parent.product') binds to a valid property, but it's not inside the data-bind. 外部的值绑定('value:$ parent.product')绑定到有效的属性,但不在数据绑定内。 It should look more like this: 它看起来应该像这样:

<select data-bind="options: products, 
                           optionsText: 'name',
                            value: product">
                           </select>

Note: I removed the optionsCaption, because it will overwrite your 'product' object (the object with name, price, and quantity) with just the string in the optionsCaption. 注意:我删除了optionsCaption,因为它只会用optionsCaption中的字符串覆盖您的“产品”对象(名称,价格和数量的对象)。 This messes up any bindings that rely on the 'product' object properties later. 这会弄乱以后依赖“产品”对象属性的所有绑定。

As for the other fields you wish to display: 至于您希望显示的其他字段:

    <td><span data-bind="value: price" /></td>
    <td><input data-bind="value: quantity" /></td>
    <td><span data-bind="value: subtotal" /></td>

Those are currently binding to the viewModel properties price, quantity, and subtotal. 这些当前绑定到viewModel属性的价格,数量和小计。 None of which are changing (and the span's should be bound to 'text' not 'value'). 它们都没有变化(并且跨度应绑定到“文本”而不​​是“值”)。 So we need to bind those fields to the object that is getting set by the dropdown like so: 因此,我们需要将这些字段绑定到通过下拉菜单设置的对象,如下所示:

    <td><span data-bind="text: product().price" /></td>
    <td><input data-bind="value: product().quantity" /></td>
    <td><span data-bind="text: product().total" /></td>

This will display the correct values for 'price' and 'quantity'. 这将显示“价格”和“数量”的正确值。 These values are not observables, however, and will not update any computeds when they change. 但是,这些值不是可观察的,并且更改时不会更新任何计算结果。 So we need these properties to be observable in order to get the full responsive feel from typing in the quantity field and seeing the total update. 因此,我们需要观察这些属性,以便通过在数量字段中键入并查看总更新来获得完整的响应感。 I prefer creating JS objects to hold these collections of observable properties: 我更喜欢创建JS对象来保存这些可观察属性的集合:

function Product(data){
data = data || {};
var self = this;
self.name = ko.observable(data.name || "");
self.price = ko.observable(data.price || "0");
self.quantity = ko.observable(data.quantity || "0");
self.total = ko.computed(function(){
    return self.price() * self.quantity();
});
}

I moved the totaling function into this object as well, just for consistency. 为了保持一致性,我也将合计函数移到了该对象中。
To use this function you can call it by passing in an object with the appropriate properties or call it with nothing and it will get initialized to 要使用此功能,您可以通过传入具有适当属性的对象来调用它,也可以不进行任何调用而将其初始化为

{name: "", price: "0", quantity: "0"}.

This also means we have to change your list of products to use this new object, otherwise nothing in that list will have observable properties. 这也意味着我们必须更改您的产品列表才能使用此新对象,否则该列表中的任何内容都不会具有可观察的属性。 You can just wrap 'new Product()' around the existing JS objects you were using: 您可以将'new Product()'包装在使用的现有JS对象周围:

var _products = [
  new Product({
      "name": "1948 Porsche 356-A Roadster",
      "price": 53.9
      , quantity: 1
  }),
  new Product({
      "name": "1948 Porsche Type 356 Roadster",
      "price": 62.16
      , quantity: 1
  }),
  new Product({
      "name": "1949 Jaguar XK 120",
      "price": 47.25
      , quantity: 1
  }),
  new Product({
      "name": "1952 Alpine Renault 1300",
      "price": 98.58
      , quantity: 1
  }),
  new Product({
      "name": "1952 Citroen-15CV",
      "price": 72.82
      , quantity: 1
  }),
  new Product({
      "name": "1956 Porsche 356A Coupe",
      "price": 98.3
      , quantity: 1
  }),
  new Product({
      "name": "1957 Corvette Convertible",
      "price": 69.93
      , quantity: 1
  })];

You can see the whole thing with all the changes I mentioned in this fiddle: http://jsfiddle.net/7e0vujf5/11/ 您可以看到我在此提琴中提到的所有更改的全部内容: http : //jsfiddle.net/7e0vujf5/11/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM