KnockoutJS油门输入

时间:2013-04-10 15:30:01

标签: input knockout.js throttling extender

我正在尝试使用KnockoutJS实现类型安全的ViewModel。在我开始通过HTML输入标签更新observable之前,它工作得非常好。

我已经实现了type扩展程序,它返回计算的observable:

return ko.computed({
    read: target,
    write: fixer
})

fixer类似于:

function (newValue) {
    var current = target(),
        valueToWrite = (newValue == null ? null : fixNumber(newValue, 0));

    if (valueToWrite !== current) target(valueToWrite);
    else if (newValue !== current) target.notifySubscribers(valueToWrite);
}

fixNumber

function fixNumber(value, precision) {
    if (value == null || value === '') return null;

    var newValue = (value || '').toString().replace(/^[^\,\.\d\-]*([\.\,\-]?\d*)([\,\.]?\d*).*$/, '$1$2').replace(/\,/, '.'),
        valueToWrite = Number(newValue);

    return !!(valueToWrite % 1) ? round(valueToWrite, precision) : valueToWrite;
}

看起来不是那么简单,但我必须考虑使用逗号作为小数分隔符。

一旦用户按下键以立即反映此更改,我通常需要更新我的observable:

<input type="text" data-bind="value: nonThrottled, valueUpdate: 'afterkeyup'"></input>

这里出现了很多问题,例如,我不能在那里输入小于1(0.1,0.2等)的十进制值。

当我试图扼杀一个观察者时,它大部分都有效。但有时用户输入和类型修复程序不同步,所以看起来有些输入偶尔会丢失。

完整的例子是http://jsfiddle.net/mailgpa/JHztW/。我真的很感激任何提示,因为我花了好几天时间来解决这些问题。

更新11/04/2013

我解决了提供自定义value绑定的问题,所以现在受限制的observables偶尔不会吃掉我的输入。

我添加了额外的valueThrottle选项绑定来限制元素值的更新:

var valueThrottle = allBindingsAccessor()["valueThrottle"];
var valueThrottleTimeoutInstance = null;

/* ... */

if (valueThrottle) {
    clearTimeout(valueThrottleTimeoutInstance);
    valueThrottleTimeoutInstance = setTimeout(function () {
      ko.selectExtensions.writeValue( element, ko.utils.unwrapObservable(valueAccessor()) );
    }, valueThrottle);
  } else applyValueAction();

另外我注意到在我的情况下无法输入0.2这样的值来自原始value绑定中的声明:

if ((newValue === 0) && (elementValue !== 0) && (elementValue !== "0"))
    valueHasChanged = true;

我把它重写为

if ((newValue === 0) && (elementValue != 0))
    valueHasChanged = true;

至少在Chrome上有效,但我没有正确测试,甚至不确定它是否正确。

要添加示例,由于某种原因,jsFiddle不接受我的自定义绑定。

任何评论都非常感谢。

0 个答案:

没有答案