我想构建一个像jsTree这样的Treeview。每次用户点击列表中的项目时,都应该添加一个显示所有包含文件的叶子:
我的ViewModel属性self.tree有一个包含所有文件夹和子文件夹的数组。当我想添加一个叶子(单击的文件夹)时,我的属性self.tree中的结构是正确的,但是observerbleArray似乎对我的操作没有反应。
这是我的ViewModel:
function TreeviewViewModel()
{
var self = this;
self.tree = ko.observableArray([
{
"data" : "C:/"
}
]);
self.expandBranch = function (item)
{
/* add leaf to clicked item -> observable does not react */
item['leaf'] = [
{ "data" : "Documents" },
{ "data" : "Photos" },
{ "data" : "Videos" }
];
}
console.log(self.tree());
}
console.log(self.tree());
证明我的属性self.tree
包含了叶子。但我的观点没有显示出来。
我的观点:
<script type="text/html" id="ULTemplate">
<ul>
<li>
<ins class="item-icon" data-bind="click: $root.expandBranch"></ins>
<a href="#" data-bind="text: data"></a>
<!-- ko if: $data.hasOwnProperty("leaf") -->
<!-- ko template: { name: 'ULTemplate', foreach: leaf } -->
<!-- /ko -->
<!-- /ko -->
</li>
</ul>
</script>
<div id="treeview" data-bind="template: { name: 'ULTemplate', foreach: tree }">
</div>
我知道,我的观点是正确的。它用假人测试了它:
dummy = [{
"data": "C:/",
"leaf": [
{ "data": "Documents" },
{ "data": "Photos" },
{ "data": "Videos" }
]
}];
self.tree(dummy);
答案 0 :(得分:1)
以下是一个工作示例:http://jsfiddle.net/G5XJe/
我对您的代码所做的更改
<li>
<ins class = "item-icon"> </ins>
<a href="#" data-bind="text: data, click: $root.expandBranch"></a >
<!-- ko template: { name: 'ULTemplate', foreach: leaf } -->
<!-- /ko -->
</li>
然后是JavaScript。我从一开始就将leaf属性添加到那里并使其成为一个可观察的数组,这允许添加更多项目并允许它通知敲除更改。
var self = this;
self.tree = ko.observableArray([{
"data": "C:/",
"leaf": ko.observableArray([])
}]);
self.expandBranch = function (item) {
/* add leaf to clicked item -> observable does not react */
item['leaf'].push({
"data": "Documents",
"leaf": ko.observableArray([])
});
item['leaf'].push({
"data": "Photos",
"leaf": ko.observableArray([])
});
item['leaf'].push({
"data": "Videos",
"leaf": ko.observableArray([])
});
}
更新
看看这个,我添加了一个属性,只允许点击一次项目:http://jsfiddle.net/G5XJe/1/