繁体   English   中英

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

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

我正在学习knockout.js。 因此,我尝试构建一个样本购物车,最初会在其中附带产品数据。 当用户选择任何产品时,将在正确的输入控件中填写相应的价格和数量,并通过计算的属性自动计算小计。

最初,当我运行程序时,将显示一个购物车的数据,但是当我选择任何产品时,价格和数量值都不会被填满,也没有小计。 我是KO的新手,那为什么为什么我犯了一个愚蠢的错误,而这个错误却在我眼前变得不明显。 所以,请指导我哪里出错了。

这是我的完整代码

 <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>

所以这里有一些问题。 首先,您对下拉列表的绑定格式不正确

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

值字段在数据绑定内声明为属性“ id”,而在视图模型中看不到该属性。 外部的值绑定('value:$ parent.product')绑定到有效的属性,但不在数据绑定内。 它看起来应该像这样:

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

注意:我删除了optionsCaption,因为它只会用optionsCaption中的字符串覆盖您的“产品”对象(名称,价格和数量的对象)。 这会弄乱以后依赖“产品”对象属性的所有绑定。

至于您希望显示的其他字段:

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

这些当前绑定到viewModel属性的价格,数量和小计。 它们都没有变化(并且跨度应绑定到“文本”而不​​是“值”)。 因此,我们需要将这些字段绑定到通过下拉菜单设置的对象,如下所示:

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

这将显示“价格”和“数量”的正确值。 但是,这些值不是可观察的,并且更改时不会更新任何计算结果。 因此,我们需要观察这些属性,以便通过在数量字段中键入并查看总更新来获得完整的响应感。 我更喜欢创建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();
});
}

为了保持一致性,我也将合计函数移到了该对象中。
要使用此功能,您可以通过传入具有适当属性的对象来调用它,也可以不进行任何调用而将其初始化为

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

这也意味着我们必须更改您的产品列表才能使用此新对象,否则该列表中的任何内容都不会具有可观察的属性。 您可以将'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
  })];

您可以看到我在此提琴中提到的所有更改的全部内容: http : //jsfiddle.net/7e0vujf5/11/

暂无
暂无

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

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