KnockoutJs实现树性结构列表

本文主要是利用ko框架遍历读取递归数据格式

如果遇到这样的数据结构,用ko框架实现是非常简单的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//data
var dataTree=[
{
"id":"4",
"text":"产品中心",
"pid":"0",
"children":[
{"id":"9","text":"展品组","pid":"4","children":[]},
{"id":"10","text":"网站分析组","pid":"4","children":[]},
{"id":"8","text":"设计组","pid":"4","children":[]},
{"id":"7","text":"文案策划","pid":"4","children":[]}
]
},
{
"id":"28",
"text":"商业智能中心",
"pid":"0",
"children":[
{"id":"29","text":"数据分析组","pid":"28","children":[]}
]
},
{
"id":"15",
"text":"推广中心",
"pid":"0",
"children":[
{
"id":"16",
"text":"营销推广",
"pid":"15",
"children":[
{"id":"17","text":"媒介采购组","pid":"16","children":[]}
]
}
]
}]

像这种层级不确定的数据结构,一般都是递归实现的,如果用原生或jq实现可能要写很多代码,但是用ko框架实现就非常简单。
用ko实现,其方法就是通过template绑定,通过模板将数据render到页面。模板绑定对于构建嵌套结构的页面非常方便。
现在我们先来把模板写好:

1
2
3
4
5
6
7
8
9
10
11
12
13
<script id="guideTmpl" type="text/html">
<li >
<div data-bind="click:$root.toggleSelect,attr:{id:id,class:'item '+(children.length>0 ? 'bold' :'')}">
<span data-bind='text: text'></span>
<!--ko if:children.length>0-->
<span data-bind="text:isOpen() ? '[-]' : '[+]'"></span>
<!--/ko-->
</div>
<!--ko if:isFolder-->
<ul data-bind="template: { name: 'guideTmpl', foreach: children }"></ul>
<!--/ko-->
</li>
</script>

下面我们就在页面上使用该模板:

1
2
3
4
5
6
<div class="userGroupTree">
<p data-bind="click:mainOpen"><span>请选择所属分支</span></p>
<!--ko if:isShow-->
<ul data-bind="template: { name: 'guideTmpl', foreach: menus }"></ul>
<!--/ko-->
</div>

页面操作相关js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
var dataTree=[
{
"id":"4",
"text":"产品中心",
"pid":"0",
"children":[
{"id":"9","text":"展品组","pid":"4","children":[]},
{"id":"10","text":"网站分析组","pid":"4","children":[]},
{"id":"8","text":"设计组","pid":"4","children":[]},
{"id":"7","text":"文案策划","pid":"4","children":[]}
]
},
{
"id":"28",
"text":"商业智能中心",
"pid":"0",
"children":[
{"id":"29","text":"数据分析组","pid":"28","children":[]}
]
},
{
"id":"15",
"text":"推广中心",
"pid":"0",
"children":[
{
"id":"16",
"text":"营销推广",
"pid":"15",
"children":[
{"id":"17","text":"媒介采购组","pid":"16","children":[]}
]
}
]
},
{
"id":"18",
"text":"销售团队",
"pid":"0",
"children":[
{"id":"19","text":"nnn","pid":"18","children":[]},
{"id":"26","text":"aaa","pid":"18","children":[]},
{"id":"25","text":"lujing","pid":"18","children":[]},
{"id":"24","text":"weidian","pid":"18","children":[]},
{"id":"23","text":"山谷","pid":"18","children":[]},
{"id":"22","text":"cimei","pid":"18","children":[]},
{"id":"21","text":"yuexiu","pid":"18","children":[]},
{"id":"20","text":"panyu","pid":"18","children":[]}
]
},
{
"id":"6",
"text":"IT技术部",
"pid":"0",
"children":[
{"id":"14","text":"服务器运维","pid":"6","children":[]},
{"id":"13","text":"网站前端组","pid":"6","children":[]},
{"id":"11","text":"网站开发组","pid":"6","children":[]},
{"id":"12","text":"后台系统组","pid":"6","children":[]}
]
}];
//给每个层级对象添加isOpen和isFolder属性
function addAttribute(dst){
for(var i=0;i<dst.length;i++){
var temp=dst[i];
temp.isOpen=ko.observable(false);
temp.isFolder=ko.observable(false);
for(var j=0;j<temp.children.length;j++){
addAttribute(temp.children);
}
}

}
addAttribute(dataTree);
var TreeModel = function() {
this.menus=ko.observableArray(dataTree);
this.isShow=ko.observable(false);
//展开、折叠操作
this.toggleSelect = function(e){
var open=e.isOpen();
e.isFolder(true);
if(open){
e.isFolder(false);
e.isOpen(false);
}else{
e.isFolder(true);
e.isOpen(true);
}
};
this.mainOpen=function(e){
var opened = e.isShow();
if(opened){
e.isShow(false);
}else{
e.isShow(true);
}

}
};
//Knockout调用applyBindings激活TreeModel(即把myViewModel和View中的声明式绑定data-bind接洽关系起来)
ko.applyBindings(new TreeModel());

运行效果:
图片1

See the Pen Pure CSS Whac-A-Mole by Deep Toaster (@deeptoaster) on CodePen.

热评文章