我有一个嵌套的HTML列表,当我点击展开一个节点时,我需要动态加载新项目。我找到并修改了this snippet但是当我尝试在列表中推送新节点时出现错误:
<!DOCTYPE html>
<html>
<head>
<link data-require="font-awesome@*" data-semver="3.0.2" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/3.0.2/css/font-awesome.min.css" />
<script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="knockout@*" data-semver="2.3.0" src="http://knockoutjs.com/downloads/knockout-2.3.0.js"></script>
<script data-require="knockout.mapping@*" data-semver="2.3.5" src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.3.5/knockout.mapping.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script type="text/html" id="tree-node">
<li>
<span class="node-toggle" data-bind="visible: expanded, click: toggle">–</span>
<span class="node-toggle" data-bind="visible: collapsed, click: toggle">+</span>
<span class="node-label" data-bind="text: name, click: $root.selected"></span>
<div data-bind="if: expanded">
<ul data-bind="template: {name: 'tree-node', foreach: children}"></ul>
</div>
</li>
</script>
</head>
<body>
<h1>Example Tree</h1>
<p>Click on the plus sign to expand a node, click on the label to select it.</p>
<ul data-bind="template: {name: 'tree-node', data: root}"></ul>
<div data-bind="if: selected">
<div data-bind="with: selected">
Selected Node: <span data-bind="text: name"></span>
</div>
</div>
</body>
</html>
HTML
// Code goes here
$(function() {
function TreeNode(values) {
var self = this;
ko.mapping.fromJS(values, { children: { create: createNode }}, this);
this.expanded = ko.observable(false);
this.collapsed = ko.computed(function() {
return !self.expanded();
})
}
TreeNode.prototype.toggle = function () {
this.expanded(!this.expanded());
if (this.expanded() && !this.children().length){
// This throw an error
this.children.push(TreeNode(
{id: "xxxx", name: "Node xxxx", children: []}
));
}
};
function createNode(options) {
return new TreeNode(options.data);
}
var root = new TreeNode({ id: "1", name: "Root", children: [
{ id: "1.1", name: "Node 1", children: [
{id: "1.1.1", name: "Node 1.1", children: []},
{id: "1.1.2", name: "Node 1.2", children: []}
]},
{ id: "1.2", name: "Node 2", children: []}
]});
var viewModel = {
root: root,
selected: ko.observable()
};
ko.applyBindings(viewModel, $('html')[0]);
});
JS
/* Styles go here */
ul, li {
list-style: none;
}
.node-label {
cursor: pointer;
}
.node-toggle {
display: inline-block;
width: 1em;
cursor: pointer;
}
CSS
{{1}}
理想情况下,解决方案应该适用于无限的嵌套级别。任何人都可以给我一个提示吗?
答案 0 :(得分:1)
TreeNode
是一个构造函数,但是你在行中没有new
的情况下调用它
this.children.push(TreeNode(
{id: "xxxx", name: "Node xxxx", children: []}
));
这只是你必须注意的其中一个问题。如果您使用strict mode,则在未使用this
调用的构造函数中使用new
将是undefined
而不是全局对象。这可能有所帮助。