【问题标题】:Knockout.js modify value before ko.observable() writeKnockout.js 在 ko.observable() 写入之前修改值
【发布时间】:2013-04-16 19:39:19
【问题描述】:

我有一个包含许多变量的工作视图模型。

我使用 autoNumeric (http://www.decorplanit.com/plugin/) 在文本框中进行文本格式化。我想在计算的 observable 中使用输入字段的观察数据,但如果带有格式的 observable 文本字段被修改,格式也会保存在变量中。

如何只观察输入字段的值而不进行格式化?

我认为最好的方法可能是对 observable 使用 getter/setter,并在设置值时删除格式。我在敲除的文档中找不到为 ko.observable() 编写 get/set 方法的解决方案,并且 ko.computed() 无法存储值。

我不想使用隐藏字段或额外变量。
没有它这可能吗?

【问题讨论】:

    标签: javascript jquery knockout.js number-formatting


    【解决方案1】:

    解决方案,见http://knockoutjs.com/documentation/extenders.html

    ko.extenders.numeric = function(target, precision) {
    //create a writeable computed observable to intercept writes to our observable
    var result = ko.computed({
        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);
                }
            }
        }
    });
    
    //initialize with current value to make sure it is rounded appropriately
    result(target());
    
    //return the new computed observable
    return result;
    };
    

    后来

    function AppViewModel(one, two) {
      this.myNumberOne = ko.observable(one).extend({ numeric: 0 });
      this.myNumberTwo = ko.observable(two).extend({ numeric: 2 });
    }
    

    【讨论】:

    • 这也会创建一个额外的变量 (result = ko.computed(...))
    • 但不在视图模型中。
    【解决方案2】:

    您可以为此使用 ko.computed()。可以指定写选项,见Writeable computed observables

    示例(取自淘汰文档):

    function MyViewModel() {
       this.price = ko.observable(25.99);
    
       this.formattedPrice = ko.computed({
           read: function () {
               return '$' + this.price().toFixed(2);
           },
           write: function (value) {
               // Strip out unwanted characters, parse as float, then write the raw data back to the underlying "price" observable
               value = parseFloat(value.replace(/[^\.\d]/g, ""));
               this.price(isNaN(value) ? 0 : value); // Write to underlying storage
           },
           owner: this
       });
    }
    
    ko.applyBindings(new MyViewModel());
    

    【讨论】:

    • 正如我所说的“ko.computed() 不能存储值”
    • 我也想避免创建更多变量。不是答案。
    • 但是如果您使用写入选项,您可以存储一个值。您是否查看过文档?
    • 我认为正确的方法是创建一个扩展器。
    • his.price(isNaN(value) ? 0 : value); // 写入底层存储 -> 你必须使用另一个变量来存储值
    猜你喜欢
    • 2017-07-18
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多