为什么一个财产没有得到可观察的knockout.js

时间:2015-06-03 09:26:40

标签: knockout.js

这是我的完整代码。

当我运行程序时,它正在运行,但是当我更改数量值时,小计不会被更改。

如果可能,有人可以通过我的代码告诉我需要在代码中修复哪个区域吗?

完整代码

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) 
{
    modalController.preferredContentSize = CGSizeMake(frameSize.x, frameSize.y); 
}
else 
{
    modalController.view.superview.frame = CGRectMake((screenWidth - frameSize.x)/2, (screenHeight - frameSize.y)/2, frameSize.x, frameSize.y);

}

2 个答案:

答案 0 :(得分:2)

快速摘要,数量文本框由所选产品的数量填充,因为带有绑定。价格可观察价格的静态值为1,现在我们从select元素中获得了选定的价格。另外,我认为_products数组中不需要数量属性。

我已修改以下评论,

  

HTML

<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: product'></select>
        </td>
        <td data-bind='with: product'>
            <span data-bind='text: formatCurrency(price)'></span>
        </td>
        // removed the data-bind here because it was getting the quantity assigned to the product
        // not from the input text box
        <td>
            <input data-bind='value: quantity, valueUpdate: "afterkeydown"' />
        </td>
        <td><span data-bind='text: subtotal()'></span></td>
    </tr>
</script>
  

的JavaScript

    var _products = [
    {
        "name": "1948 Porsche 356-A Roadster",
        "price": 53.9,
        "quantity": 1
    },
    {
        "name": "1948 Porsche Type 356 Roadster",
        "price": 62.16,
        "quantity": 2
    },
    {
        "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(null); // set to null as it holds your selected product from the select element

    //self.price = ko.observable(1); do not this
    self.quantity = ko.observable(1);

    self.subtotal = ko.computed(function () {
        if (!self.product()) // on load self.product() will be null, return to avoid error
            return;
        // you get the select products price and multiple it by the quantity from the textbox
        return formatCurrency(self.product().price * self.quantity());
    });

};

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());

这很有效。

由于

答案 1 :(得分:0)

我从@Super Cool得到了一个很好的答案,我只是修改了他的代码。喜欢在这里分享更改的代码。这里是jsfiddle链接http://jsfiddle.net/tridip/3bu6nybk/

<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",
                               optionsCaption:"--Select--",
                               value: product'>
                               </select>
        </td>

        <td>
            <span data-bind='text:price' ></span>
        </td>
        <td>
            <input data-bind='value:quantity' />
        </td>

        <td ><span data-bind='text:subtotal()'></span></td>

    </tr> 
</script>    

var _products = [
      {
          "name": "1948 Porsche 356-A Roadster",
          "price": 53.9,
          "quantity": 1
      },
      {
          "name": "1948 Porsche Type 356 Roadster",
          "price": 62.16,
          "quantity": 2
      },
      {
          "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) {
           alert(value.toFixed(2));
          return "$" + value.toFixed(2);
      }

      var CartLine = function () {
          var self = this;
          self.products = ko.observableArray(_products);
          self.product = ko.observable(1);
          self.price = ko.observable(1);
          self.quantity = ko.observable(1);   
          self.product.subscribe(function(item){
              if(!item)
              { 
                 self.price(0);
                 self.quantity(0);
                 return;
              }
             self.price(item.price);
             self.quantity(item.quantity);
          });

          self.subtotal = ko.computed(function () {

              return self.price() * self.quantity();
          },self);
      };

      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());