使用淘汰赛在文本框上触发onchange事件

时间:2018-05-31 11:15:03

标签: knockout.js

这里正在制作一个片段,以便使用淘汰赛完成计算,附件就是小提琴。

https://jsfiddle.net/naren_net/55etxj4y/272/



var vm = function() {
  this.PrevActualQty = ko.observable();
  this.PrevUnitCost = ko.observable();
  this.PrevTotalCost = ko.observable();

  this.ChangeQty = ko.observable(0);
  this.ChangeUnitCost = ko.observable(0);
  this.ChangeTotalCost = ko.observable(0);

  this.NewActualTotalCost = ko.observable(0);



  this.PrevTotalCost = ko.computed(function() {
    return (isNaN(this.PrevActualQty() * this.PrevUnitCost()) ? "" : this.PrevActualQty() * this.PrevUnitCost());
  }, this);

  this.NewActualQty = ko.computed(function() {
    return ((isNaN(this.PrevActualQty()) ? 0 : Number(this.PrevActualQty())) + (isNaN(this.ChangeQty()) ? 0 : Number(this.ChangeQty())));
  }, this);

  this.NewActualUnitCost = ko.computed(function() {
    return (isNaN(this.PrevUnitCost()) ? 0 : Number(this.PrevUnitCost()) + (isNaN(this.ChangeUnitCost()) ? 0 : Number(this.ChangeUnitCost())));
  }, this);

  this.NewActualTotalCost = ko.computed(function() {
    return (isNaN(this.NewActualQty()) ? 0 : Number(this.NewActualQty()) * (isNaN(this.NewActualUnitCost()) ? 0 : Number(this.NewActualUnitCost())));
  }, this);

  this.ChangeTotalCost = ko.computed(function() {
    return ((this.NewActualTotalCost()) - (this.PrevTotalCost()));
  }, this);

  this.ChangeTotalCost.subscribe(function(newValue) {
    alert(newValue);
  });

  this.Changed = function() {
    alert("fired");
    this.NewActualTotalCost(this.ChangeTotalCost() + this.PrevTotalCost());
  }
}


ko.applyBindings(new vm());

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table>
  <th>
    <td align=center>Qty</td>
    <td align=center>Unit Cost</td>
    <td align=center>Total Cost</td>
  </th>
  <tr>
    <td>Prev Actual</td>
    <td><input type=textbox data-bind='value:PrevActualQty' style='text-align:right'></td>
    <td><input type=textbox data-bind='value:PrevUnitCost' style='text-align:right'></td>
    <td><input type=textbox data-bind='value:PrevTotalCost()' style='text-align:right'></td>
  </tr>
  <tr>
    <td>Actual</td>
    <td align=right><input type=textbox data-bind='value:ChangeQty' style='text-align:right'></td>
    <td align=right><input type=textbox data-bind='value:ChangeUnitCost' style="text-align:right"></td>
    <td align=right><input type=textbox data-bind="value:ChangeTotalCost, event:{onchange:Changed}" , style="text-align:right"></td>

    <td><span data-bind="text:ChangeTotalCost"></span></td>
  </tr>
  <tr>
    <td>New Actual</td>
    <td align=right><span data-bind="text:NewActualQty"></span></td>
    <td align=right><span data-bind="text:NewActualUnitCost"></span></td>
    <td align=right><span data-bind="text:NewActualTotalCost"></span></td>
  </tr>
</table>
&#13;
&#13;
&#13;

问题是文本框上的onchange值为:ChangeTotalCost不会触发。 我想捕获更新的值并重新计算NewActualTotalCost的值。该方法有问题吗?

谢谢!

感谢您的回复! 当用户更新任何新实际行,即实际数量/实际单位成本/实际总成本时,用户可以更新的当前数据行应该计算新实际行数据。 所有这三个都是可计算的,前两个工作正常,但第三个(ChangeTotalCost)应该使用PrevTotalCost + NewActualTotalCost更新NewActualTotalCost并且应该将ActualUnitCost计算为(NewActualTotalCost / NewActualQty) - PrevActualUnitCost

1 个答案:

答案 0 :(得分:0)

当knockout更新输入时,没有change事件。这些事件只会受到用户互动的影响。

使用<input>元素和淘汰时,通常根本不会绑定change事件;您subscribe改为数据绑定值!

不幸的是,你通过这样做创建了一个循环依赖:

  1. ChangeTotalCost依赖于NewActualTotalCost
  2. ChangeTotalCost更改时,您希望Changed方法更新NewActualTotalCost
  3. 返回1,因为依赖项已更改
  4. 我并不完全清楚你的逻辑应该是什么。如果您可以澄清行之间的关系,我可以帮助寻找基于错误事件的方法的替代方案。