Ищите здесь проверку на вменяемость. Недавно я начал изучать нокаут, и мне поручили преобразовать существующую многоступенчатую форму.
Основная идея заключается в проверке каждого шага, прежде чем позволить пользователю продолжить. Также установлены определенные ограничения (не показаны), которые определяют, следует ли продолжить работу или отправить с использованием всех текущих данных (например, если они не соответствуют требованиям).
Вот скрипка с упрощенной версией (фактическая форма содержит около 40 полей за 4 шага)
http://jsfiddle.net/dyngomite/BZcNg/
HTML:
<form id="register">
<fieldset>
<h2>About You</h2>
<ul>
<li>
<label for="firstName">First Name:</label>
<input type="text" data-bind="value: firstName" required="required" />
</li>
<li>
<label for="lastName">Last Name</label>
<input type="text" data-bind="value: lastName" required="required" />
</li>
</ul>
</fieldset>
<fieldset>
<h2>Your Business</h2>
<ul>
<li>
<label for="businessName">Business Name:</label>
<input type="text" data-bind="value: businessName" required="required" />
</li>
<li>
<label for="currentCustomer">Were you referred by someone?</label>
<input type="checkbox" data-bind="checked: referred" />
</li>
</ul>
</fieldset>
<fieldset>
<h2>User Info</h2>
<ul>
<li>
<label for="userName">Referrer's First Name:</label>
<input type="text" data-bind="value: referralFirst" required="required" />
</li>
<li>
<label for="password">Referrer's Last Name:</label>
<input type="password" data-bind="value: referralLast" required="required" />
</li>
</ul>
</fieldset>
</form>
<div class="nav-buttons"> <a href="#" data-bind='click: stepForward'>Continue</a>
<a href="#" data-bind='click: stepBack'>Back</a>
<a href="#" data-bind='click: resetAll'>Cancel</a>
</div>
JS:
$("#register").children().hide().first().show();
ko.validation.init({
parseInputAttributes: true,
decorateElement: true,
writeInputAttributes: true,
errorElementClass: "error"
});
function myViewModel() {
var self = this;
//observable init
self.firstName = ko.observable();
self.lastName = ko.observable();
self.businessName = ko.observable();
self.referred = ko.observable();
self.referralFirst = ko.observable();
self.referralLast = ko.observable();
//validaiton observable init
self.step1 = ko.validatedObservable({
firstName: self.firstName,
lastName: self.lastName
});
self.step2 = ko.validatedObservable({
businessName: self.businessName,
referred: self.referred
});
self.step3 = ko.validatedObservable({
referralFirst: self.referralFirst,
referralLast: self.referralLast
});
//navigation init
self.currentStep = ko.observable(1);
self.stepForward = function () {
if(self.currentStep()<4){
self.changeSection(self.currentStep() + 1);
}
}
self.stepBack = function () {
if (self.currentStep() > 1) {
self.changeSection(self.currentStep() - 1);
}
}
self.changeSection = function(destIdx){
var validationObservable = "step" + self.currentStep();
if(self[validationObservable]().isValid()){
self.currentStep(destIdx);
$("#register").children().hide().eq(self.currentStep() - 1).show();
return true;
}else{
self[validationObservable]().errors.showAllMessages();
}
return false;
}
self.resetAll = function(){
//TODO
return false;
}
}
ko.applyBindings(new myViewModel());
Мои вопросы:
Имеет ли смысл объявить все поля изначально как наблюдаемые, а затем сгруппировать их вместе в validatedObservables()?
Если в конце я хочу отправить всю форму, есть ли более разумный способ сделать это, чем объединение каждого шага с помощью ko.toJSON(self.step1()). Нужно ли мне создавать наблюдаемую «полную форму», содержащую все наблюдаемые входные данные? Другими словами, как лучше всего сериализовать полную форму? Хотел бы я использовать ko.toJSON(self) ?
Каков наилучший способ сбросить форму до первоначальной конфигурации? Есть ли способ повторно применить ko.applyBindings(new myViewModel())?
Я правильно об этом говорю?
Спасибо за любые разъяснения.