渡された一連の構成オプションと最終的にページにバインドされるViewModelに基づいて動的ウィザードを構築するように設計された、再利用可能なコントロール/カスタムバインディングとテンプレートがあります。ウィザードが適切に構築され、必要なすべてのフィールドが表示されていますが、これまでのところ、実際の入力フィールド値を表示することはできません。
何か案は?
ViewModel
var user = function () {
var self = this;
self.FirstName = ko.observable("Brent");
self.LastName = ko.observable("Pabst");
self.Email = ko.observable("me@brentpabst.com");
self.FullName = ko.computed(function () {
return self.FirstName() + " " + self.LastName();
});
};
var tenant = function () {
var self = this;
self.Name = ko.observable("Tenant Name");
self.SubDomain = ko.observable("Sub Domain");
self.User = ko.observableArray([new user]);
self.wizardModel = new merlin.wizard({
title: "Add a Tenant",
model: self,
steps: [
{ Title: "Tenant Information",
Fields: [
{ Name: "Name", Label: "Organization Name", Value: "Name" },
{ Name: "SubDomain", Label: "Login Page", Value: "SubDomain" }
]
},
{ Title: "Administrator Information",
Fields: [
{ Name: "FirstName", Label: "First Name", Value: "User.FirstName" },
{ Name: "LastName", Label: "Last Name", Value: "User.LastName" },
{ Name: "Email", Label: "E-Mail Address", Value: "User.Email" }
]
}
]
});
self.save = function () {
alert(ko.toJSON(self));
};
};
ko.applyBindings(tenant());
ウィザードモデル
merlin.wizard = function (config) {
var self = this;
self.steps = config.steps;
self.title = config.title;
self.model = config.model;
self.currentStep = ko.observable(0);
};
テンプレートとバインディング
var templateEngine = new ko.nativeTemplateEngine();
templateEngine.addTemplate = function (templateName, templateMarkup) {
document.write("<script type=\"text/html\" id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
};
templateEngine.addTemplate("merlin_wizard", "\
<form class=\"m-ui-wizard\">\
<h1 data-bind=\"text: title\" />\
<h2 data-bind=\"text: title\" />\
<div class=\"m-ui-wizard-steps\" data-bind=\"foreach: steps\">\
<div class=\"m-ui-wizard-step\">\
<!-- ko if: $data.Fields -->\
<!-- ko foreach: Fields -->\
<label data-bind=\"text: Label, attr: { for: Name }\"></label>\
<input type=\"text\" data-bind=\"attr: { name: Name }, Value: typeof value === 'function' ? Value($root.model) : $root.model[Value]\" />\
<!-- /ko -->\
<!-- /ko -->\
</div>\
</div>\
</form>");
ko.bindingHandlers.wizard = {
init: function () {
return { controlsDescendantBindings: true };
},
update: function (element, viewModelAccessor, allBindingsAccessor) {
var viewModel = viewModelAccessor(), allBindings = allBindingsAccessor();
while (element.firstChild)
ko.removeNode(element.firstChild);
var wizTemplateName = allBindings.gridTemplate || "merlin_wizard";
var wizContainer = element.appendChild(document.createElement("DIV"));
ko.renderTemplate(wizTemplateName, viewModel, { templateEngine: templateEngine }, wizContainer, "replaceNode");
}
};
HTMLスニペット
<div data-bind="wizard: wizardModel"></div>
注:これをFiddleでまったく機能させることができませんでした。この設定で、Fiddleの限界を押し上げている可能性があるという事実以外に、理由はよくわかりません。