Ich glaube, ich habe ein bisschen bessere Lösung mit keine Baumwurzel (oder ich vermute mehrere Baumwurzeln). Bitte schau es dir an:
http://jsfiddle.net/nonsense66/Bzekr/
Schablone:
<script id="treeElement" type="text/html">
<li>
<span data-bind="text: name"></span>
<ul data-bind="template: { name: 'treeElement', foreach: children }">
</ul>
</li>
</script>
<ul data-bind="template: { name: 'treeElement', foreach: $data.treeRoot }"></ul>
Javascript:
var viewModel = {
treeRoot: ko.observableArray()
};
var TreeElement = function(name, children) {
var self = this;
self.children = ko.observableArray(children);
self.name = ko.observable(name);
}
var tree = [
new TreeElement("Russia", [
new TreeElement("Moscow")
]),
new TreeElement("United States",
[
new TreeElement("New York", [
new TreeElement("Harlem"),
new TreeElement("Central Park")
])
])
];
viewModel.treeRoot(tree);
ko.applyBindings(viewModel);
Ich hoffe es hilft!
Dieser Beitrag war mir eine große Hilfe. Ich finde immer neue Wege, Knockout einzusetzen. Ich wollte nur eine nützliche Modifikation hinzufügen, die genau das tut, was nemesv vorgeschlagen hat, nur mit dem ko.mapping-Plugin.
//Nested javascript object:
var formElementNode = {
children: [{
children: [],
text: 'Child1',
value: 'Value1'
}, {
children: [{
children: [{
children: [],
text: 'Child2.1.1',
value: 'Value2.1.1'
}],
text: 'Child2.1',
value: 'Value2.1'
}],
text: 'Child2',
value: 'Value2'
}, {
children: [],
text: 'Child3',
value: 'Value3'
}],
text: 'Main',
value: 'MainValue'
};
//Use ko.mapping to generate viewModel:
var viewModel = ko.mapping.fromJS(formElementNode);
ko.applyBindings(viewModel);
Wie hier gezeigt jsFiddle.
Rekursive benutzerdefinierte Bindung
Eine andere Lösung, nachdem ich gelesen habe, dass Vorlagen langsamer sind, überlege ich, mit rekursiver Bindung zu gehen.
<ul data-bind="nestMe: name"></ul>
ko.bindingHandlers.nestMe = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var observable = valueAccessor() || { };
var unwrapped = ko.unwrap(observable);
ko.utils.setHtml(element, '<li>'+unwrapped+'<ul data-bind="foreach: children"><li data-bind="nestMe: name" /></ul></li>');
}
};
var rootModel = function(name, children) {
this.name = ko.observable(name);
this.children = ko.observableArray(children);
};
var basemodel = new rootModel('test');
basemodel.children.push(new rootModel('aaa',[new rootModel('111'),new rootModel('222')]));
basemodel.children.push(new rootModel('bbb'));
basemodel.children.push(new rootModel('ccc',[new rootModel('333'),new rootModel('444')]));
ko.applyBindings(basemodel);
Die Möglichkeit zu haben, vor der Rekursion mit Daten zu spielen, sollte sich als nützlich erweisen.
JSFiddle