【问题标题】:Can knockout validation extend a validateObservable to validating against entire model?淘汰赛验证可以将 validateObservable 扩展到针对整个模型进行验证吗?
【发布时间】:2012-12-18 10:19:36
【问题描述】:

我将 Knockout 用于绑定到具有一定深度/复杂性的 ViewModel 的视图。

要验证我的 ViewModel,我需要计算整个 VM 树(遍历和比较后代)。我希望利用敲除验证插件@https://github.com/ericmbarnard/Knockout-Validation 创建一些任意自定义验证规则并报告任何错误。

我使用 KO 计算的 observable @http://jsfiddle.net/drdamour/ZrVZ7/ 设置了一种可能的方法。验证规则是确保没有 2 个 SubCollections 具有相同的值。这是有效的,但它没有使用 Knockout-Validation,我的规则现在在我的计算 observable 中实现,这似乎是错误的。

我的问题与Knockout Validation validatedObservable group error 非常相似,但我发现发现的解决方案(托管在http://jsfiddle.net/CGuW2/6/)不太理想:

var viewModel = {
    num1: ko.observable("50").extend({ number: true, min: 0, max: 100 }),
    num2: ko.observable("50").extend({ number: true, min: 0, max: 100 })
};

viewModel.isValidSum = ko.validatedObservable({
                            num1: viewModel.num1,
                            num2: viewModel.num2
                        }).extend({ mustEqual: 100 });

ko.applyBindings(viewModel);

因为它通过将经过验证的 self 作为属性添加到自身 (isValidSum) 来复制 ViewModel。我试图消除这种冗余@http://jsfiddle.net/drdamour/5B8s4/,但视图无法绑定到已验证的Observable:

var viewModel = {
    num1: ko.observable("50").extend({ number: true, min: 0, max: 100 }),
    num2: ko.observable("50").extend({ number: true, min: 0, max: 100 })
};

var vm = ko.validatedObservable(viewModel).extend({ mustEqual: 101 });

ko.applyBindings(vm);

这可能是 KO 或 KO-Validation 的错误,或者我可能只是做错了。

所以问题是:在淘汰赛中确定 VM 是否针对跨 VM 的多个属性和层进行评估的条件有效的最佳方法是什么?

【问题讨论】:

    标签: validation mvvm knockout.js knockout-validation


    【解决方案1】:

    我通过grouping 我想在模型上验证的可观察对象采取不同的方法来验证我的模型,从而避免了这辆马车盘旋:

    这是一些用于设置我的阶段的初始化代码(您可以查看所有可用的选项Here

        ko.validation.init({
            registerExtenders: true,
            parseInputAttributes: true,
            grouping: { deep: true, observable: false }
        });
    

    那么我会像这样设置你的模型:

    function testModel() {
        var self = this;
        self.num1 = ko.observable(100).extend({ number: true, min: 0, max: 100 });
        self.num2 = ko.observable(50).extend({ number: true, min: 0, max: 100 });
    
        self.sum = ko.observable(150).extend({ number: true, equal: 100 });
        self.num1.subscribe(function () {
            self.sum(self.num1() + self.num2());
        });
        self.num2.subscribe(function () {
            self.sum(self.num1() + self.num2());
        });
    
        self.errors = ko.validation.group(this);
    }
    
    var viewModel = new ViewModel();
    
    //somewhere later where we are testing the model
    if (viewModel.sum.isValid())
        //YAY!!!
    else
       //this will update the UI as you have configured it to show the error messages
       viewModel.errors.showAllMessages(); 
    

    使用ko.validation.group(model) 将导致验证遍历模型中的所有可观察对象(多深,取决于初始设置,您会注意到我创建了我的grouping: { deep: true },这意味着如果内部有带有可观察对象的子模型这个模型也可以验证这些。

    如果您想隔离不同的验证案例,您不仅可以对整个模型执行此操作,还可以对其中的部分执行此操作。

    编辑:

    这是一种满足您的要求的方法,它确实有效。订阅所有要针对某个条件进行验证的可观察对象并不理想,但您唯一的选择是将它们简单地分组到一个已验证的Observable 中,这意味着您的数据最有可能首选结构。

    【讨论】:

    • 这个例子没有做最重要的部分,即验证这两个数字的总和为 100。我想我可以在计算中进行检查..但现在我没有使用 KO -验证这是我想要使用的,因为我已经在我的真实场景中为此定义了规则。还要检查我等效的computedObservable 答案jsfiddle.net/drdamour/ZrVZ7,它就是这样做的,但我对此并不满意(见问题)。最后,validatedObservable 应该只是 group() 的包装,其中包括 isValid
    • 我确实错过了最重要的要求。我更新了我的答案以展示一种可以处理您的场景的方法。这不是性感的速记代码,但不幸的是,这是我觉得缺乏淘汰赛验证的一个领域......针对特定条件验证可验证组。所以你在这里没有太多选择。
    • validatedObservable 是我想要的,但它似乎不起作用。
    猜你喜欢
    • 2013-06-22
    • 2012-02-18
    • 2015-07-18
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2018-06-05
    • 2015-02-03
    相关资源
    最近更新 更多