KnockoutJS дроссельной заслонки

Я пытаюсь реализовать что-то вроде безопасных типов ViewModel с использованием KnockoutJS. Он работает довольно хорошо, пока я не начну обновлять наблюдаемые через теги ввода HTML.

Я реализовал type Экстендер, который возвращает вычисляемую наблюдаемость:

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;
}

Это выглядит не так просто, но я должен рассмотреть возможность использования запятой в качестве десятичного разделителя.

Часто мне нужно обновить мои наблюдаемые, как только пользователь нажмет клавишу, чтобы немедленно отразить это изменение:

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

И здесь возникает много проблем, потому что, например, я не могу ввести десятичные значения меньше 1 (0,1, 0,2 и т. Д.).

Когда я пытаюсь подавить наблюдаемое, это в основном работает. Но иногда пользовательский ввод и фиксатор типов не синхронизируются, поэтому иногда кажется, что некоторые вводы теряются.

Полный пример есть http://jsfiddle.net/mailgpa/JHztW/. Я был бы очень признателен за любые советы, так как я потратил несколько дней, пытаясь решить эти проблемы.

ОБНОВЛЕНИЕ 11/04/2013

Я решил мою проблему с предоставлением пользовательских value привязка, так что теперь наблюдаемые объекты не время от времени потребляют мой вклад.

Я добавил дополнительную привязку опции valueThrottle к обновлению throttle значения элемента:

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 ответов

Другие вопросы по тегам