使用validatedObservable的ko.validation给了我奇怪的结果

时间:2013-06-03 16:08:35

标签: knockout.js knockout-validation

我使用 ko.validation 检查我网页上的有效数据,如下所示:

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

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

然后在我的确定按钮中,我在提交之前检查验证:

var buttonOk = function () {

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

效果很好:如果用户没有为邮政编码输入内容,并且说明验证失败。

现在我添加了一些验证规则:

postcodeMustNotAlreadyExists + denominationMustNotAlreadyExists就像这样:

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)

有什么想法吗?

感谢。

2 个答案:

答案 0 :(得分:6)

尝试使用以下内容覆盖viewModel中的isValid()函数:

self.isValid = ko.computed(function () {
        return ko.validation.group(
            self,
            {
                observable: true,
                deep: true
            }).showAllMessages(true);
    }, self);

答案 1 :(得分:0)

isValid属性仅在observable.subscribe处理程序中的validationObservable中重新定义,这意味着它很可能不会使用.extend重新定义,并且使用先前版本的ko.validation它甚至不会更新随着对象的变化。

使用undefined / null初始化经过验证的observable时也存在问题,而不是传递对象 - >然后永远不会更新isValid定义以匹配新的可观察对象。

最后但并非最不重要的是Tom Studee在他的回答中提出的选项可以并且应该在ko.validation.init(app level)或ko.validationObservable定义级别定义。它绝对更具可读性和可维护性。在这里' deep:true'很可能是你失败了,因为你的视图模型中有一个循环引用。

另外在isValid计算上调用showAllMessages将阻止仅在修改后显示消息(ko.validation酷功能之一),这会导致ex。典型地创建新的实体表单以完全覆盖验证消息。虽然通常你会看到它们只传递不正确的值或试图保存它们。

总结:确保您已更新ko.validation,在validationObservsable或app级别传递选项,仅在需要时调用showAllMessages。创建ko.validationObservable,将空选项object {}作为第二个构造函数参数传递;如果没有其他选项,则将isValid属性重新定义为ko.validation.group的新调用。