ko.validation с validatedObservable дает мне странный результат

Я использую ko.validation для проверки достоверности данных на моей странице следующим образом:

var postcode = ko.observable(),
    name = ko.observable();

var validationModel = ko.validatedObservable({
    postcode: postcode.extend({ required: true }),
    name: name.extend({ required: true })
});

Затем в моей кнопке OK я проверяю проверку перед отправкой:

var buttonOk = function () {

    if (!validationModel.isValid()) {
        validationModel.errors.showAllMessages();
        return false;
    }
    ...

Это работает очень хорошо: если пользователь не набирает что-то для почтового индекса и имени, проверка не удалась.

Теперь я добавил еще несколько правил проверки:

почтовый индексMustNotAlreadyExists + наименованиеMustNotAlreadyExists вот так:

var validationModel = ko.validatedObservable({
    postcode: postcode.extend({ required: true }),
    name: name.extend({ required: true })
}).extend({
    postcodeMustNotAlreadyExists: cities,
    denominationMustNotAlreadyExists: cities
});

ko.validation.rules['postcodeMustNotAlreadyExists'] = {
    validator: function (val, cities) {
        // Try to find a match between the typed postcode and the postcode in the list of cities
        var match = ko.utils.arrayFirst(cities(), function (item) {
            return (val.postcode() === item.postCode());
        });            
        return !match;
    },
    message: 'This postcode already exists!'
};
ko.validation.rules['denominationMustNotAlreadyExists'] = {
    validator: function (val, cities) {
        // Try to find a match between the typed denomination and the denomination in the list of cities
        var match = ko.utils.arrayFirst(cities(), function (item) {
            return (val.name() === item.name());
        });
        return !match;
    },
    message: 'This denomination already exists!'
};
ko.validation.registerExtenders();

Теперь validationModel.isValid() всегда возвращает true, когда пользователь ничего не вводит для почтового индекса или имени. И я заметил, что validationModel().postcode.isValid() является ложным, поэтому нелогично устанавливать для validationModel.isValid() значение True.

Теперь с моей новой реализацией я должен проверить две вещи: (!validationModel.isValid() || validationModel().errors().length>0)

Есть идеи?

Спасибо.


person Bronzato    schedule 03.06.2013    source источник


Ответы (2)


Попробуйте переопределить функцию isValid() внутри вашей модели представления с помощью:

self.isValid = ko.computed(function () {
        return ko.validation.group(
            self,
            {
                observable: true,
                deep: true
            }).showAllMessages(true);
    }, self);
person Tom Studee    schedule 05.06.2013
comment
мне пришлось переключиться глубоко на false, так как это приводило к переполнению стека.. но это переопределение, по-видимому, то, что мне нужно, чтобы myModel.isValid() начал работать. в документации это не казалось нужным? - person Sonic Soul; 06.11.2013

Свойство isValid переопределяется только в обработчике validationObservable in observable.subscribe, что означает, что оно, скорее всего, не будет переопределено с помощью .extend, а с предыдущей версией ko.validation оно не будет обновляться даже при изменении объекта.

Существуют также проблемы с инициализацией проверенного наблюдаемого объекта с помощью undefined/null и без передачи объектов -> тогда определение isValid никогда не обновляется, чтобы соответствовать новому наблюдаемому объекту.

И последнее, но не менее важное: параметры, предложенные Томом Стьюди в своем ответе, могут и должны быть определены в ko.validation.init (уровень приложения) или на уровне определения ko.validationObservable. Это определенно более читабельно и ремонтопригодно. Здесь 'deep: true', скорее всего, не работает для вас, потому что у вас есть циклическая ссылка в вашей модели представления.

Кроме того, вызов showAllMessages на вычислении isValid предотвратит отображение сообщений только после модификации (одна из интересных функций ko.validation), что приводит к ex. типичная форма создания новой сущности, которая будет полностью покрыта сообщениями проверки. В то время как обычно вы видите их, только неправильные значения передаются или пытаются их сохранить.

Подводя итог: убедитесь, что вы обновили ko.validation, передайте параметры на уровне validationObservsable или приложения, вызывайте showAllMessages только при необходимости. Создайте ko.validationObservable, передав пустой объект параметров {} в качестве второго аргумента конструктора; Если не работает другой вариант, переопределите свойство isValid на новый вызов ko.validation.group.

person mikus    schedule 19.10.2015