每次按下链接时都会添加一个文本框,然后当我按下每个文本框旁边的详细信息链接时,它应显示一个jQuery对话框。我在堆栈溢出时发现了一些东西但是无法使它与我的模型一起工作。这是jsFiddle:http://jsfiddle.net/SuperJohn/se7kC/1/
这是HTML:
<div data-bind="template: { name: 'page-template', data: form.pages()[designer.pageId()] }"></div>
<script type="text/html" id="page-template">
<div>
<div id="fields" data-bind="template: { name: $root.designer.template.field, foreach: $data.fields }"></div>
<div>
<ul>
<li>
<a href="#" data-bind="click: $root.designer.add.field.text">Text Box</a>
</li>
</ul>
</div>
</div>
</script>
<script type="text/html" id="field-nav">
<a href="#" data-bind="click: $root.editDetails">Details</a>
</script>
<script type="text/html" id="text-template">
<div>
<div data-bind="template: { name: 'field-nav' }"></div>
<label data-bind="text: $data.title"></label>
<input type="text" data-bind="value: $data.valText" />
<div data-bind="jqDialog: {autoOpen: false, modal: true}, template: {name: 'textDetails', data: $parent.selectedTool, if: $parent.selectedTool}, openDialog: $parent.selectedTool"></div>
</div>
</script>
<script type="text/html" id="textDetails">
<div data-bind="attr: {id: $data.id}">
<fieldset>
<legend>Field</legend>
<div>
<label>Label</label>
<input type="text" data-bind="value: $data.title" />
</div>
</fieldset>
<button data-bind="jqButton: {}, click: $root.accept">Accept</button>
<button data-bind="jqButton: {}, click: $root.cancel">Cancel</button>
</div>
</script>
这是JS模型:
function PageForm(id) {
this.id = ko.observable(id);
this.fields = ko.observableArray([]);
}
function DesignerForm(id) {
this.pages = ko.observableArray([new PageForm(id)]);
}
var ViewModel = function ()
{
var self = this;
self.form = new DesignerForm(0);
ko.bindingHandlers.jqDialog = {
init: function(element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {};
//handle disposal
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).dialog("destroy");
});
//dialog is moved to the bottom of the page by jQuery UI. Prevent initial pass of ko.applyBindings from hitting it
setTimeout(function() {
$(element).dialog(options);
}, 0);
}
};
//custom binding handler that opens/closes the dialog
ko.bindingHandlers.openDialog = {
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (value) {
$(element).dialog("open");
} else {
$(element).dialog("close");
}
}
};
//custom binding to initialize a jQuery UI button
ko.bindingHandlers.jqButton = {
init: function(element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {};
//handle disposal
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).button("destroy");
});
$(element).button(options);
}
};
self.selectedTool = ko.observable();
self.editDetails = function(detailsToEdit) {
self.selectedTool(detailsToEdit);
};
self.accept = function() {
self.selectedTool().accept();
self.selectedTool("");
},
self.cancel = function() {
self.selectedTool().cancel();
self.selectedTool("");
}
self.designer = {
"pageId": ko.observable(0),
"add":
{
"field":
{
"text": function ()
{
var pg = self.designer.pageId();
var idx = self.form.pages()[pg].fields().length;
var fld = {
"id": idx,
"type": "text",
"title": "Textbox Label",
"valText": ""
};
self.form.pages()[pg].fields.push(ko.mapping.fromJS(fld));
}
}
},
"template": {
"field": function (item)
{
// check for knockout bug
if (typeof item.type == 'function') {
return item.type() + '-template';
} else {
return item.type + '-template';
}
}
}
};
};
ko.applyBindings(new ViewModel());