Knockout Validation不适用于动态下拉列表

时间:2015-09-03 13:32:38

标签: asp.net-mvc knockout-validation

我一直在MVC 5 Web App中使用knockoutjs(3.3.0)和knockout-validation(2.0.3)来创建一个表单,该表单除了其他字段外,还根据另一个字段动态显示多个选择列表对选择列表值(即选择一个停止次数,并显示正确的目的地/持续时间对数)。

Knockout验证适用于所有其他字段,使用下面的代码,除了动态添加的目标/持续时间对,我可以看到失败验证,(如果你不选择目的地),但它失败了选中时更新并通过验证。我尝试在init和viewmodel中设置{deep:true}分组,但仍然没有飞镖。

这是https://jsfiddle.net/2c9o2cpu/39/

下面代码的缩写
Destination = function (name, value) {
    var self = this;
    this.name = ko.observable(name).extend({
        required: true
    });
    this.value = ko.observable(value).extend({
        required: true
    }).extend({
        min: 1
    });
    self.errors = ko.validation.group(self);
}

Duration = function (name, value) {
    var self = this;
    this.name = ko.observable(name).extend({
        required: true
    });
    this.value = ko.observable(value).extend({
        required: true
    });
    self.errors = ko.validation.group(self);
}


function EnquiryViewModel() {

    var self = this;
    self.Stops = ko.observable([{
        "Id": 1,
        "Name": "1 stop"
    }, {
        "Id": 2,
        "Name": "2 stops"
    }, {
        "Id": 3,
        "Name": "3 stops"
    }, {
        "Id": 4,
        "Name": "4 stops"
    }]);
    self.selectedTitle = ko.observable();
    self.selectedStops = ko.observable();

    self.Destinations = ko.observable([{
        "Id": 0,
        "Name": "Destination?"
    }, {
        "Id": 2,
        "Name": "San Francisco"
    }, {
        "Id": 3,
        "Name": "Wine Country"
    }, {
        "Id": 4,
        "Name": "Mountain Areas"
    }]);
    self.selectedDestination = ko.observable();
    self.Durations = ko.observable([{
        "Id": 1,
        "Name": "1 night"
    }, {
        "Id": 2,
        "Name": "2 nights"
    }, {
        "Id": 3,
        "Name": "3 nights"
    }]);
    self.selectedDuration = ko.observable();

    self.FirstName = ko.observable().extend({
        required: true
    });


    self.destinationData = ko.observableArray([]);
    self.destinationlistData = ko.observable({});
    self.datadest = ko.observable({});

    self.durationData = ko.observableArray([]);
    self.durationlistData = ko.observable({});
    self.datadur = ko.observable({});

    self.fieldNum = 0;

    // predefine observables for those shown
    self.destinationlistData()["field0"] = ko.observableArray([]);
    self.durationlistData()["field0"] = ko.observableArray([]);

    self.datadest()["field0"] = ko.observable();
    self.datadur()["field0"] = ko.observable();

    self.removeDestination = function (item) {
        self.destinationData.remove(item);
        self.durationData.remove(item);
        self.fieldNum--;
    }

    self.addDestination = function () {
        var field = "field" + self.fieldNum++;

        if (!ko.isObservable(self.destinationlistData()[field])) self.destinationlistData()[field] = ko.observableArray([]);

        if (!ko.isObservable(self.datadest()[field])) self.datadest()[field] = ko.observable();

        if (!ko.isObservable(self.durationlistData()[field])) self.durationlistData()[field] = ko.observableArray([]);

        if (!ko.isObservable(self.datadur()[field])) self.datadur()[field] = ko.observable();


        // populate destinations
        var data1 = '[{"Id":0,"Name":"Destination?"},{"Id":2,"Name":"San Francisco"},{"Id":3,"Name":"Wine Country"},{"Id":4,"Name":"Mountain Areas"}]';
        //self.destinationlistData()[field].push(new Destination("Destination?", 0));

        $.each($.parseJSON(data1), function (i, dest) {
            self.destinationlistData()[field].push(new Destination(dest.Name, dest.Id));
        });

        var data2 = '[{"Id":1,"Name":"1 night"},{"Id":2,"Name":"2 nights"},{"Id":3,"Name":"3 nights"}]';
        self.durationlistData()[field].push(new Duration("Duration?", 0));

        $.each($.parseJSON(data2), function (i, dur) {
            self.durationlistData()[field].push(new Duration(dur.Name, dur.Id));
        });


        self.destinationData.push(field);
        self.durationData.push(field);

    }

    self.addDestination();

    self.Save = function () {

        if (self.errors().length === 0) {


            var jsonData = ko.toJSON(self);
            //console.log(jsonData);
            // for now, post the entire thing as a string. We'll trim this down with a model
            //$.post("/Home/Save", { jsonData: jsonData });
            alert("Validation Passed");

        } else {
            alert('Validation Failed');
            console.log(self.errors().length);
            console.dir(self.errors);
            self.errors.showAllMessages();

        }

    };

    //self.errors = ko.validation.group(self, { deep: true });
    self.errors = ko.validation.group(self);

    self.stopsChanged = function (obj, event) {

        if (event.originalEvent) { // user

            var stops = self.selectedStops();

            if (stops === 0) {
                self.destinationData.removeAll();
                self.durationData.removeAll();
            }

            if (stops < self.destinationData().length) {
                self.destinationData.splice(stops);
                self.durationData.splice(stops);
            } else {
                if (stops >= 1) {
                    var existing = self.destinationData().length || 0;
                    for (var i = 0; i < (stops - existing); i++) {
                        self.addDestination();
                    }
                }
            }

        } else { // system
            // ..
        }
    }

}



ko.validation.init({
    registerExtenders: true,
    decorateElement: true,
    errorElementClass: 'err',
    errorMessageClass: 'err',
    insertMessages: true,
    decorateInputElement: true,
    //grouping: { deep: true },
    messagesOnModified: false
}, true);


var vm = new EnquiryViewModel();

ko.applyBindings(vm, document.getElementById("test"));

0 个答案:

没有答案