ko.validation с многошаговыми моделями в стиле мастера

Я пытаюсь преобразовать этот ответ для использования ko.validation.

Я застрял в том, чтобы включить следующую кнопку только тогда, когда состояние модели допустимо, однако мой код ниже не оценивается правильно:

self.modelIsValid = function() {
        self.currentStep().model().isValid();
};

В настоящее время я застрял и был бы признателен за свежий взгляд. Модель проверяет OK (с показанными сообщениями об ошибках), последним шагом будет проверка каждой модели с помощью modelIsValid, который управляет следующей кнопкой.

jsfiddle находится здесь, а код ниже.

ko.validation.configure({
    insertMessages: false,
    decorateElement: true,
    errorElementClass: 'error'
});

function Step(id, name, template, model) {
    var self = this;
    self.id = id;
    self.name = ko.observable(name);
    self.template = template;
    self.model = ko.observable(model);

    self.getTemplate = function() {
        return self.template;
    };
}

function ViewModel(model) {
    var self = this;

    self.nameModel = ko.observable(new NameModel(model));    
    self.addressModel = ko.observable(new AddressModel(model));

    self.stepModels = ko.observableArray([
            new Step(1, "Step1", "nameTmpl", self.nameModel()),
            new Step(2, "Step2", "addressTmpl", self.addressModel()),
            new Step(3, "Confirmation", "confirmTmpl", {NameModel: self.nameModel(), AddressModel:self.addressModel()})]);

    self.currentStep = ko.observable(self.stepModels()[0]);

    self.currentIndex = ko.computed(function() {
        return self.stepModels.indexOf(self.currentStep());
    });

    self.getTemplate = function(data) {
        return self.currentStep().template();
    };

    self.canGoNext = ko.computed(function() {
        return (self.currentIndex() < (self.stepModels().length - 1));
    });    

    self.modelIsValid = function() {
        self.currentStep().model().isValid();
    };

    self.goNext = function() {
        if (((self.currentIndex() < self.stepModels().length - 1) && ($('.validationMessage:visible').length <= 0))) {
            self.currentStep(self.stepModels()[self.currentIndex() + 1]);
        }
    };

    self.canGoPrevious = ko.computed(function() {
        return self.currentIndex() > 0;
    });

    self.goPrevious = function() {
        if ((self.currentIndex() > 0 && ($('.validationMessage:visible').length <= 0))) {
            self.currentStep(self.stepModels()[self.currentIndex() - 1]);
        }
    };
}

NameModel = function (model) {
    var self = this;

    //Observables
    self.FirstName = ko.observable(model.FirstName).extend({ required: true });
    self.LastName = ko.observable(model.LastName).extend({ required: true });

    return self;
};

AddressModel = function(model) {
    var self = this;

    //Observables
    self.Address = ko.observable(model.Address).extend({ required: true });;
    self.PostalCode = ko.observable(model.PostalCode).extend({ required: true });;
    self.City = ko.observable(model.City).extend({ required: true });;

    return self;
};

     var viewModelFromServer = {
        "FirstName": "John",
        "LastName": "Doe",
        "Address": "123 Main St",
        "PostalCode": "53201",
        "City": "Milwaukee"
    };

ko.applyBindings(new ViewModel(viewModelFromServer));

Изменить ответ Кевина

Окончательное представление не отображалось, это оказалось связано с тем, что для представления не была определена группа проверки, поэтому вы изменили функцию modelIsValid на следующее:

self.modelIsValid = ko.computed(function () {
    if (typeof(self.currentStep().model().isValid) != "undefined") { 
        return self.currentStep().model().isValid();
    }
    else
        return true; // no validation used for viewmodel, so just return true
});

Кажется, это работает, хотя я очень новичок в javascript!


person morleyc    schedule 17.07.2013    source источник


Ответы (1)


вы применили правила проверки к отдельным наблюдаемым в вашей модели имени и адреса, но вы пытаетесь использовать сгруппированные функции без явного группирования в каждой модели:

NameModel = function (model) {
    var self = this;

    //Observables
    self.FirstName = ko.observable(model.FirstName).extend({ required: true });
    self.LastName = ko.observable(model.LastName).extend({ required: true });

    ko.validation.group(self);

    return self;
};

также вам нужно будет сделать modelIsValid вычисляемым наблюдаемым:

self.modelIsValid = ko.computed(function() {
    return self.currentStep().model().isValid();
});

обновленная скрипта - http://jsfiddle.net/jnTjW/4/

person Kevin Nacios    schedule 17.07.2013
comment
спасибо @Kevin, почти готово, но с вашей скрипкой страница подтверждения не выгружается (она всегда выгружается только до шага 2). Я посмотрю, смогу ли я понять, почему, а пока какие-нибудь идеи? - person morleyc; 17.07.2013
comment
Я решил это, пожалуйста, смотрите последний раздел моего вопроса для обновления - person morleyc; 17.07.2013