使用映射在动态表单上进行敲除验证

时间:2014-07-01 09:36:09

标签: knockout.js knockout-mapping-plugin knockout-validation

我试图在动态表单上进行验证,因为有些日子我无法得到它。 我很乐意帮助你。

我需要使用从Web服务收到的信息扩展ViewModel的属性。 我试图个性化映射,但在复选框的情况下,从数组的每个值输入一次。此外,在无线电和复选框的情况下,只需在第一个中应用所需的属性,只是出现一次验证消息。

var answerMapping = {
    "values": {
        create: function(options) {                    
            var answer = ko.observable(options.data);                        
            answer.extend({
                required: {
                    onlyIf: function () { return (options.parent.required() === true); }
                }
            });     
            return answer;
        }
    },  
    "value": {
        create: function(options) {                    
            var answer = ko.observable(options.data);                        
            answer.extend({
                required: {
                    onlyIf: function () { return (options.parent.required() === true); }
                }
            });     
            if (options.parent.type() === 3) {
                answer.extend({ number: true, min: options.parent.min, max: options.parent.max });
            }
            if (options.parent.type() === 4) {
                answer.extend({ dateISO: true });
            }
            return answer;
        }
    }
};

您可以在自定义映射之前在jsfiddle中看到示例: jsfiddle

1 个答案:

答案 0 :(得分:0)

你的小提琴有几个问题。

主要问题是required验证器不能像这样用于可观察数组(似乎它只检查内容是否为空,而不是数组为空)。

您可以改用此自定义验证器:

ko.validation.rules['requiredNonEmpty'] = {
    validator: function (val, other) {
        console.log(val);
        return val !== null && val.length > 0;
    },
    message: "Required non empty"
}
ko.validation.registerExtenders();

其他问题包括:

  • values声明为observable而不是observableArray
  • 一些缺失的括号(minmax
  • 分组不深(myVM.errors = ko.validation.group(myVM, {deep: true});

如果要显示values observableArray的消息,请添加以下内容:

<span data-bind="validationMessage: values"></span>

更新

你是对的。问题是values: { create: function(options) {} }中的每个值都会调用values: ["A1", "A2"],而不是整个数组。

您必须在映射后添加验证:(

像这样:

self.load = function (data) {
    ko.mapping.fromJSON(data, answerMapping, self);
    for (var i = 0; i < self.questions().length; i++) {
        var question = self.questions()[i];
        if (ko.isObservable(question.values) 
            && question.values() instanceof Array) {
            question.values.extend({
                requiredNonEmpty: {
                    onlyIf: function () { return (question.required()=== true); }
                }
            });
        }
    }
};

并删除映射中的values部分。

Updated fiddle