敲除输入类型编号向上或向下检测以从 observableArray 添加或删除项目

Knockout input type number detect up or down to add or remove item from observableArray

使用以下代码,我想计算使用 input type="number" 添加的项目的总成本。

<div data-bind="foreach: availableItems()">
<br />
  <input type="number" data-bind="event: {change: $parent.itemCountChange}" min="0" step="1" value="0" />
  <label data-bind="text: name"/>
</div>
<label id="totalCost" data-bind="text: totalCost" />

JS:

var refreshmentsModel = function ref() {
  var self = this;
  self.totalCost = ko.observable(0);
  self.addedItems = ko.observableArray();
  self.availableItems = ko.observableArray([{name: "Tea", price: 3.00}, {name: "Coffee", price: 4.00}, {name: "Cake", price: 5.00}]);
  self.itemCountChange = function(d) {
    self.addedItems.push(d);
    alert("Added items now: " + self.addedItems().length)
  }
};
ko.applyBindings(new refreshmentsModel());

但是我不知道是增加了还是减少了,所以我的 addedItems 总是会添加新项目,即使数量减少了。 我已经尝试添加绑定到数字输入的值,但随后绑定到 foreach 中的每个输入,因此更改一个会更改所有输入。

也许重新设计并有两个按钮会更容易,一个用于添加,一个用于删除,但如果有人对以上内容有任何想法,那就太好了!

谢谢

PS。抱歉,我尝试用代码创建代码笔,但它一直给我错误 'ko is not defined',即使我在设置 window.

中添加了敲除参考

我认为所有需要做的就是在可用项目的数据上添加一个可观察的字段,它保存订购的值。然后有一个 computed observable 在订购东西时进行计算。

像这样。

function ItemModel(data) {
  var self = this;
  self.name = ko.observable(data.name || 'unknown');
  self.price = ko.observable(data.price || 0.00);
  self.numberOrdered = ko.observable(data.numberOrdered || 0.00);
  self.itemCost = ko.pureComputed(function() {
    return parseFloat(self.numberOrdered()) * parseFloat(self.price());
  });
}

var data = [{
  name: "Tea",
  price: 3.00
}, {
  name: "Coffee",
  price: 4.00
}, {
  name: "Cake",
  price: 5.00
}];

var refreshmentsModel = function ref() {
  var self = this;

  function totalCostCalc(accumulator, currentValue) {
    return accumulator + currentValue.itemCost();
  }

  self.totalCost = ko.pureComputed(function() {
    return self.availableItems().reduce(totalCostCalc, 0);
  });
  self.addedItems = ko.observableArray();
  self.availableItems = ko.observableArray(data.map(x => new ItemModel(x)));
};
ko.applyBindings(new refreshmentsModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table>
  <theader>
    <tr>
      <td>Name</td>
      <td>Ordered</td>
      <td>Price</td>
      <td>Item Total</td>

    </tr>
  </theader>
  <tbody data-bind="foreach: availableItems()">
    <tr>
      <td><label data-bind="text: name" /></td>
      <td>
        <input type="number" data-bind="textInput: numberOrdered" min="0" step="1" value="0" />
      </td>
      <td data-bind="text: price">
      </td>
      <td data-bind="text: itemCost">
      </td>
    </tr>
  </tbody>
  <tfooter>
    <tr>
      <td>Total cost</td>
      <td></td>
      <td></td>
      <td data-bind="text: totalCost"></td>

    </tr>
  </tfooter>
</table>