【问题标题】:ko.validation with validatedObservable gives me strange result带有validatedObservable的ko.validation给了我奇怪的结果
【发布时间】:2013-05-29 20:44:43
【问题描述】:

我使用 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() 在用户不输入任何邮政编码或姓名时总是返回真。我注意到validationModel().postcode.isValid() 是假的,因此将validationModel.isValid() 设置为True 是不符合逻辑的。

现在有了我的新实现,我必须测试两件事:(!validationModel.isValid() || validationModel().errors().length>0)

有什么想法吗?

谢谢。

【问题讨论】:

    标签: knockout.js knockout-validation


    【解决方案1】:

    尝试在 viewModel 中覆盖 isValid() 函数:

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

    【讨论】:

    • 我不得不将 deep 切换为 false,因为它给了我一个堆栈溢出。但这个覆盖似乎是 myModel.isValid() 开始工作所需要的。在文档中似乎不需要它?
    【解决方案2】:

    isValid 属性仅在 observable.subscribe 处理程序的 validationObservable 中重新定义,这意味着它很可能不会使用 .extend 重新定义,并且对于以前版本的 ko.validation,即使对象更改也不会更新.

    使用 undefined / null 初始化已验证的 observable 以及不传递对象也存在问题 -> 然后 isValid 定义永远不会更新以匹配新的 observable 对象。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      • 2017-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-13
      • 2018-03-13
      相关资源
      最近更新 更多