Пользовательская проверка, вызывающая срабатывание вычисленных значений

Для быстрого просмотра моей проблемы я сделал рабочий jsFiddle здесь:

В KnockoutJS я сделал собственный валидатор расширителя, чтобы проверить, является ли формат ввода в формате ЧЧММ. Если это так, он возвращает новое значение, в противном случае он вернет его к старому значению, это в настоящее время работает.

ko.extenders.acValidTimeHHMM = function (target, options) {
var result = ko.computed({
    read: target, 
    write: function (newValue) {
        var re = /^([0-9]|0[0-9]|1[0-9]|2[0-3])[0-5][0-9]$/;
        if (!re.test(newValue)) {
            target.notifySubscribers(target());
            //Time not in correct format return old time
            return;
        }
        target(newValue);
    }
}).extend({ notify: 'always' });

result(target());
return result;
};

Проблема, с которой я столкнулся, заключается в том, что я обновляю свою базу данных, когда значение изменяется с использованием вычисленного значения. Однако это также срабатывает, когда я сбрасываю значение обратно к его оригиналу, используя мой валидатор. (Метод, основанный на технике грязного флага Райана Ральфа)

self.update = ko.computed(function () {
    self.timeOne();
    self.timeTwo();
    alert("Fired");
});

Проблема, очевидно, заключается в строке target.notifySubscribeers(target()); в моем валидаторе. Однако без этой строки я не могу сбросить значение до его старого значения, и я не могу найти другой способ сделать это.

Так что это срабатывает только тогда, когда значение действительно меняется, а не валидатор, сбрасывающий его. JsFiddle точно демонстрирует мою проблему и может быть использован для создания рабочей версии (надеюсь). Я знаю, что в настоящее время она также запускается при загрузке страницы.

1 ответ

Решение

Проблема, с которой я столкнулся, заключается в том, что я обновляю свою базу данных, когда значение изменяется с использованием вычисленного значения

Я не знаю всей вашей логики, но я не думаю, что это хорошая идея обновлять БД каждый раз, когда обновляется ваша модель вида нокаута. Может быть, вы должны посмотреть на плагин валидации нокаут. Используя этот плагин, вы можете создать одно и то же пользовательское правило проверки и обновлять базу данных только в случае отправки формы.

О вашей проблеме... Самое простое решение, которое я нашел, - это отправить функцию обратного вызова успешно в расширение проверки как опцию. Как то так

JS:

var ViewModel = function() {  
    var update = function () {
        alert("value was successfully changed");
    };

    var cancel = function () {
        alert("validation failed. previous value was returned");
    };

    var timeOne = ko.observable("1100").
        extend({ 
                    acValidTimeHHMM: { 
                        success: update,
                        fail: cancel
                    }
               });

    var timeTwo = ko.observable("1248").
        extend({ acValidTimeHHMM: { success: update } });

    return {
        timeOne: timeOne,
        timeTwo: timeTwo
    };
};

ko.extenders.acValidTimeHHMM = function(target, option) {    
    var baseOptions = {
        success: null,
        fail: null
    };
    $.extend(baseOptions, option);

    var result = ko.computed({
        read: target, 
        write: function (newValue) {
            var oldValue = target();
            if(newValue == oldValue) return;

            var re = /^([0-9]|0[0-9]|1[0-9]|2[0-3])[0-5][0-9]$/;
            if (!re.test(newValue)) {
                target.notifySubscribers(oldValue);
                if(typeof(baseOptions.fail) == "function")
                    baseOptions.fail();
                return;
            }
            target(newValue);

            if(typeof(baseOptions.success) == "function")
                baseOptions.success()
        }
    }).extend({ notify: 'always' });

    result(target());
    return result;
};

ko.applyBindings(new ViewModel());

HTML:

<p>Time One<input data-bind='value: timeOne' /></p> 
<p>Time Two<input data-bind='value: timeTwo' /></p>   
Другие вопросы по тегам