サムシング(Live copy on js fiddle):
CSS:
.left {
float: left;
}
.clear {
clear: both;
}
HTML:
<p>Current:
<a href="#" data-bind="visible: (stack.length > 0), text: selectedNode().name, click: selectParentNode"></a>
<span data-bind="visible: (stack.length <= 0), text: selectedNode().name"></span>
</p>
<p class="left">Children: </p>
<ul class="left" data-bind="template: {name: 'childList', foreach: selectedNode().children}"></ul>
<script type="text/html" id="childList">
<li data-bind="click: function(){nodeViewModel.selectChildNode($data)}">
<a href="#">A${name}</a>
</li>
</script>
<br /><br />
<ul class="clear" data-bind="template: {name: 'backBtn'}"></ul>
<script type="text/html" id="backBtn">
<a href="#" data-bind="visible: $data.selectedNode().back, click: function() { nodeViewModel.selectBackNode($data.selectedNode().back) }">Back</a>
</script>
はJavaScript:
var node = function(config, parent) {
this.parent = parent;
var _this = this;
var mappingOptions = {
children: {
create: function(args) {
return new node(args.data, _this);
}
}
};
ko.mapping.fromJS(config, mappingOptions, this);
};
var myModel = {
node: {
name: "Root",
children: [
{
name: "Child 1",
back: 1,
children: [
{
name: "Child 1_1",
back: 1,
children: [
{
name: "Child 1_1_1",
back: 4,
children: [
]},
{
name: "Child 1_1_2",
back: 2,
children: [
]},
{
name: "Child 1_1_3",
back: 1,
children: [
]}
]}
]},
{
name: "Child 2",
back: 1,
children: [
{
name: "Child 2_1",
back: 1,
children: [
]},
{
name: "Child 2_2",
back: 1,
children: [
]}
]}
]
}
};
var viewModel = {
nodeData: new node(myModel.node, undefined),
selectedNode: ko.observable(myModel.node),
stack: [],
selectBackNode: function(numBack) {
if (this.stack.length >= numBack) {
for (var i = 0; i < numBack - 1; i++) {
this.stack.pop();
}
}
else {
for (var i = 0; i < this.stack.length; i++) {
this.stack.pop();
}
}
this.selectNode(this.stack.pop());
},
selectParentNode: function() {
if (this.stack.length > 0) {
this.selectNode(this.stack.pop());
}
},
selectChildNode: function(node) {
this.stack.push(this.selectedNode());
this.selectNode(node);
},
selectNode: function(node) {
this.selectedNode(node);
}
};
window.nodeViewModel = viewModel;
ko.applyBindings(viewModel);
このサンプルでは、単に無限にマッピングしますJSONデータのネストされたセットであり、実際にこの正確なコードをアプリケーションで使用すると素晴らしいと言えます。
selectBackNodeとselectParentNode
のような余分な機能のいくつかは、ツリーをバックアップに移動することができます。
例をナビゲートしている間、親ラベルは1つのレベルを上げるためのリンクになり、いくつかのリーフノードにはバックボタンがあり、指定されたレベル数だけツリーを上に戻すことができます。
--EDIT--
あなたのリーフ・ノードは、子配列を持っていない場合は、モデル内に存在しない追加データが導入された問題を取得する可能性があります。
これは、HJ05素晴らしい作品です。答えをありがとう。 –
+1スタックadtの使用 – booyaa
jsFiddleのようなリンクは素敵な*付属*ですが、常に関連するコードとマークアップ**を回答自体に入れます**。理由:http://meta.stackexchange.com/questions/118392/add-stack-overfow-faq-entry-or-similar-for-putting-code-in-the-question私はあなたのためにこれでやった機会。 –