【问题标题】:fire onchange event on textbox using knockout使用敲除在文本框上触发 onchange 事件
【发布时间】:2018-11-10 09:24:51
【问题描述】:

这里正在使用 sn-p 来完成计算,并附上小提琴。

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>

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

谢谢!


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

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    当淘汰赛更新输入时,没有change 事件。这些事件仅由用户交互触发。

    在使用&lt;input&gt; 元素和淘汰赛时,您通常根本不会绑定到change 事件;你 subscribe 改为数据绑定值!

    不幸的是,这样做会创建循环依赖:

    1. ChangeTotalCost 依赖于 NewActualTotalCost
    2. 当ChangeTotalCost 更改时,您希望Changed 方法更新NewActualTotalCost
    3. 回到 1,因为依赖项发生了变化

    我并不完全清楚您的预期逻辑应该是什么。如果你能弄清行之间的关系,我可以帮助寻找一种替代错误的基于事件的方法。

    【讨论】:

    • 恐怕你的解释并没有让我更清楚。一开始可能会很好 a) 删除所有重复的属性声明,b) 使计算输入 readonly,以及 c) 用 numeric extender 替换 Number 解析逻辑以使事情更具可读性。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    • 2015-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多