读入淘汰计算并不总是用扩展器触发

时间:2016-10-22 15:32:59

标签: javascript knockout.js subscriber

这可能最容易用小提琴http://jsfiddle.net/LkqTU/32190/

来描述

我有一个可观察的叫价,它有一个扩展器,因此它可以舍入到两位数,并且不允许非数字。

我有一个可写的计算可观察量,它在它前面加上一个美元符号。

但是如果扩展器返回0.第二次它发生$ 0没有返回到文本框(计算的observable)所以如果我在文本框中键入hello world(计算的observable),价格正确报告0并且格式化的价格显示$ 0但是,如果我清除它并再次输入你好世界。此时价格仍为0美元,但格式化价格文本框显示问候世界(即使格式化价格报告为0美元)。必须在某个地方错过通知吗?

这是代码。

ko.extenders.numeric = function(target, precision) {
  //create a writable computed observable to intercept writes to our observable
  var result = ko.pureComputed({
    read: target, //always return the original observables value
    write: function(newValue) {
      var current = target(),
        roundingMultiplier = Math.pow(10, precision),
        newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
        valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;

      //only write if it changed
      if (valueToWrite !== current) {
        target(valueToWrite);
      } else {
        //if the rounded value is the same, but a different value was written, force a notification for the current field
        if (newValue !== current) {
          target.notifySubscribers(valueToWrite);
        }
      }
    }
  }).extend({
    notify: 'always'
  });

  //initialize with current value to make sure it is rounded appropriately
  result(target());

  //return the new computed observable
  return result;
};


function model() {
  var self = this;

  this.price = ko.observable('29.01').extend({
    numeric: '2'
  });
  this.formattedPrice = ko.computed({
    read: function() {
      return '$' + this.price()
    },
    write: function(value) {
      value = parseFloat(value.replace(/[^\.\d]/g, ""));
      this.price(isNaN(value) ? 0 : value);
    },
    owner: this
  });
}

var mymodel = new model();

$(document).ready(function() {
  ko.applyBindings(mymodel);

});

1 个答案:

答案 0 :(得分:1)

对我来说似乎有用的是扩展formattedPrice计算变量以始终通知并修改write方法以仅传入值而不是检查isNaN;你的扩展器无论如何都会执行此操作并强制为0使得if (newValue !== current)测试永远不会返回true,因为newValue和current在这种情况下总是为0(NaN!== 0 通过检查):

  this.formattedPrice = ko.computed({
    read: function() {
      return '$' + this.price()
    },
    write: function(value) {
      value = parseFloat(value.replace(/[^\.\d]/g, ""));
      this.price(value); //just pass in nan or the value so the extender can check/notify if newValue !== current
    },
    owner: this
  }).extend({
    notify: 'always'
  });

更新了小提琴:http://jsfiddle.net/LkqTU/32192/