這裡我示範的jsTree是基于ABP架構 ,展示部分代碼,話不多說首先看效果如:
1:引入JS<link href="/jstree/themes/default/style.css" rel="stylesheet" />
<script src="/jstree/jstree.js"></script>
2:頁面部分代碼
1 <div class="row">
2 <div class="col-lg-6 border_solid first_border_solid">
3 <div class="portlet light">
4 <div class="portlet-title">
5 <div class="caption">
6 <span class="caption-subject bold uppercase">
7 樹形菜單分類
8 </span>
9 <a ng-if="vm.permissions.managecategoryTree" ng-click="vm.categoryTree.addUnit(null)" class="btn btn-primary">
10 <i class="fa fa-plus"></i> 新增資源分類
11 </a>
12 </div>
13 </div>
14 <div class="portlet-body">
15 <div id="CategoryEditTree"></div>
16 <div ng-if="!vm.categoryTree.unitCount" class="text-muted">
17 目前沒有資源分類資訊
18 </div>
19 </div>
20 </div>
21 </div>
22 <div class="col-lg-5 border_solid second_border_solid">
23 <div class="portlet light">
24 <div class="portlet-title">
25 <div class="caption">
26 <span class="caption-subject bold uppercase">
27 分類
28 <span ng-if="vm.categoryTree.selectedOu.displayName">: {{vm.categoryTree.selectedOu.displayName}}</span>
29 </span>
30 </div>
31 @*<div class="actions" ng-if="vm.categoryTree.selectedOu.id">
32 <a ng-if="vm.permissions.managecategoryTree" ng-click="vm.members.openAddModal()" class="btn btn-circle btn-default">
33 <i class="fa fa-plus"></i> 添加一個資源
34 </a>
35 </div>*@
36 </div>
37 <div class="portlet-body">
38 <div ng-if="vm.categoryTree.selectedOu.id">
39 <form class="editCategoryForm">
40 <div class="form-group">
41 <label>上級分類</label>
42 <span>{{vm.categoryTree.selectedParent()}}</span>
43 </div>
44 <div class="form-group">
45 <label>分類ID</label>
46 <span>{{vm.categoryTree.selectedOu.id}}</span>
47 </div>
48 <div class="form-group">
49 <label>分類名稱</label>
50 <input type="text" value="" ng-model="vm.categoryTree.displayName" class="form-control" />
51 </div>
52 <div class="form-group">
53 <label>排序</label>
54 <input type="number" value="" ng-model="vm.categoryTree.orderId" class="form-control" />
55 </div>
56 <div class="form-group editCategory">
57 <button class="btn btn-primary" ng-click="vm.categoryTree.editCategory()">儲存</button>
58 </div>
59 </form>
60 </div>
61 <div ng-if="!vm.categoryTree.selectedOu.id" class="text-muted">
62 選擇一個分類添加成員
63 </div>
64 </div>
65 </div>
66 </div>
67 </div>
3:js部分代碼
1 //#region 操作
2 vm.categoryTree = {
3
4 $tree: null,
5
6 unitCount: 0,
7
8 // 設定根節點數量
9 setUnitCount: function (unitCount) {
10 vm.categoryTree.unitCount = unitCount;
12 },
13
14 refreshUnitCount: function () {
15 vm.categoryTree.setUnitCount(vm.categoryTree.$tree.jstree('get_json').length);
16 },
17
18 selectedOu: {
19 id: null,
20 displayName: null,
21 code: null,
22
23 set: function (ouInTree) {
24
25 if (!ouInTree) {
26 vm.categoryTree.selectedOu.id = null;
27 vm.categoryTree.selectedOu.displayName = null;
28 vm.categoryTree.selectedOu.code = null;
29 vm.categoryTree.selectedOu.parentId = null;
30 } else {
31 vm.categoryTree.selectedOu.id = ouInTree.id;
32 vm.categoryTree.selectedOu.displayName = ouInTree.original.displayName;
33 vm.categoryTree.selectedOu.code = ouInTree.original.code;
34 vm.categoryTree.selectedOu.parentId = ouInTree.parent;
35 }
36 }
37 },
38
39 // 節點右鍵菜單清單
40 contextMenu: function (node) {
41 var items = {
42 editUnit: {
43 label: '修改',
44 _disabled: !vm.permissions.managecategoryTree,
45 action: function (data) {
46 var instance = $.jstree.reference(data.reference);
47
48 vm.categoryTree.openCreateOrEditUnitModal({
49 id: node.id,
50 displayName: node.original.displayName
51 }, function (updatedOu) {
52 node.original.displayName = updatedOu.displayName;
53 instance.rename_node(node, vm.categoryTree.generateTextOnTree(updatedOu));
54 });
55 }
56 },
57
58 addSubUnit: {
59 label: '添加下級分類',
60 _disabled: !vm.permissions.managecategoryTree,
61 action: function () {
62 vm.categoryTree.addUnit(node.id);
63 }
64 },
65
73
74 'delete': {
75 label: '删除',
76 _disabled: !vm.permissions.managecategoryTree,
77 action: function (data) {
78 abp.message.confirm('确定删除', node.original.displayName, function (isConfirmed) {
79 if (isConfirmed) {
80 categoryService.deleteResourceClassAsync(node.id).then(function () { //背景服務擷取資料(AngularJs)
81 abp.notify.success('删除成功');
82 window.sweetAlert.close();
83 vm.categoryTree.reload();
84 });
85 }
86 }
87 );
88 }
89 }
90 }
91
92 return items;
93 },
94
95 // 新增節點數
96 addUnit: function (parentId) {
97
98 var instance = $.jstree.reference(vm.categoryTree.$tree);
99 vm.categoryTree.openCreateOrEditUnitModal({
100 parentId: parentId
101
102 }, function (newOu) {
103 instance.create_node(
104 parentId ? instance.get_node(parentId) : '#',
105 {
106 id: newOu.id,
107 parent: newOu.parentId ? newOu.parentId : '#',
108 code: newOu.code,
109 displayName: newOu.displayName,
110 memberCount: 0,
111 text: vm.categoryTree.generateTextOnTree(newOu),
112 state: {
113 opened: false // 是否預設展開所有節點
114 }
115 });
116
117 vm.categoryTree.refreshUnitCount();
118 });
119 },
120
121 // 打開模态框 新增或編輯
122 openCreateOrEditUnitModal: function (organizationUnit) {
123 // console.log(organizationUnit);
124 var modalInstance = $uibModal.open({
125 templateUrl: '~/App/Main/views/commoditie/createOrEditCategoryModal.cshtml',
126 controller: 'app.views.commoditie.createOrEditCategoryModal as vm',
127 backdrop: 'static',
128 resolve: {
129 organizationUnit: function () {
130 return organizationUnit;
131 }
132 }
133 });
134
135 modalInstance.result.then(function () {
136
137 vm.categoryTree.reload();
138
139 });
140 },
141
142 generateTextOnTree: function (ou) {
143 var itemClass = ou.resourceClassificationChilds.length > 0 ? ' ou-text-has-members' : ' ou-text-no-members';
144 var parentId = ou.parentId == null ? 'top' : ou.parentId;
145 return '<span title="' + ou.code + '" class="ou-text' + itemClass + '" data-ou-id="' + ou.id + '" data-parent-ou-id="' + parentId + '" data-name="' + ou.displayName + '" >' + ou.displayName + ' (<span class="ou-text-resources-count">' + ou.resourceClassificationChilds.length + '</span>) <i class="fa fa-caret-down text-muted"></i></span>';
146 },
147
148 incrementMemberCount: function (ouId, incrementAmount) {
149 var treeNode = vm.categoryTree.$tree.jstree('get_node', ouId);
150 treeNode.original.memberCount = treeNode.original.memberCount + incrementAmount;
151 vm.categoryTree.$tree.jstree('rename_node', treeNode, vm.categoryTree.generateTextOnTree(treeNode.original));
152 },
153
154 // 擷取資料
155 getTreeDataFromServer: function (callback) {
156 categoryService.getResourceClassificationListAsync({}).then(function (result) { // 背景服務擷取資料(AngularJS)
157 // console.log(result);
158 var treeData = result.data.map((item) => {
159 return {
160 id: item.id,
161 parent: item.parentId ? item.parentId : '#',
162 code: item.code,
163 displayName: item.displayName,
164 memberCount: 0, //item.memberCount,
165 text: vm.categoryTree.generateTextOnTree(item),
166 state: {
167 opened: false // 是否預設展開所有節點
168 }
169 };
170 });
171
172 callback(treeData);
173 });
174 },
175 // 編輯分類
176 editCategory: function () {
177 var editCategory = {
178 "id": vm.categoryTree.selectedOu.id,
179 "displayName": vm.categoryTree.displayName,
180 "orderId": vm.categoryTree.orderId
181 };
182 var parentId = vm.categoryTree.selectedOu.parentId;
183 parentId == '#' ? parentId = '' : parentId;
184 editCategory.parentId = parentId;
185 if (vm.categoryTree.displayName != undefined && vm.categoryTree.orderId != undefined) {
186 categoryService.updateCategoryAsync(editCategory)
187 .then(function (result) {
188 abp.notify.info('儲存成功');
189 vm.categoryTree.reload();
190 });
191 } else {
192 abp.message.warn('請輸入分類名稱或排序值');
193 }
194 // console.log(editCategory);
195 },
196 selectedParent: function () {
197 var selectedParentId = vm.categoryTree.selectedOu.parentId;
198 var parentName;
199 if (selectedParentId == '#') {
200 return '此分類是最頂級分類';
201 } else {
202 parentName = $('[data-ou-id="' + selectedParentId + '"]').attr('data-name');
203 return parentName;
204 }
205 },
206 // 初始化
207 init: function () {
208 vm.categoryTree.getTreeDataFromServer(function (treeData) {
209 vm.categoryTree.setUnitCount(treeData.length);
210 vm.categoryTree.$tree = $('#CategoryEditTree');
211
212 var jsTreePlugins = [
213 'types',
214 'contextmenu',
215 'wholerow',
216 'sort'
217 ];
218
219 if (vm.permissions.managecategoryTree) {
220 jsTreePlugins.push('dnd');
221 }
222
223 vm.categoryTree.$tree.on('changed.jstree', function (e, data) {
224 // console.log(data);
225 $scope.$apply(function () {
226 if (data.selected.length != 1) {
227 vm.categoryTree.selectedOu.set(null);
228 } else {
229 var selectedNode = data.instance.get_node(data.selected[0]);
230 vm.categoryTree.selectedOu.set(selectedNode);
231 }
232 });
233 }).jstree({
234 'core': {
235 data: treeData,
236 multiple: false,
237 check_callback: function (operation, node, node_parent, node_position, more) {
238 return true;
239 }
240 },
241 types: {
242 "default": {
243 "icon": "fa fa-folder tree-item-icon-color icon-lg"
244 },
245 "file": {
246 "icon": "fa fa-file tree-item-icon-color icon-lg"
247 }
248 },
249 contextmenu: {
250 items: vm.categoryTree.contextMenu
251 },
252 sort: function (node1, node2) {
253 if (this.get_node(node2).original.displayName < this.get_node(node1).original.displayName) {
254 return 1;
255 }
256
257 return -1;
258 },
259 plugins: jsTreePlugins
260 });
261
262 vm.categoryTree.$tree.on('click', '.ou-text .fa-caret-down', function (e) {
263 e.preventDefault();
264
265 var ouId = $(this).closest('.ou-text').attr('data-ou-id');
266 setTimeout(function () {
267 vm.categoryTree.$tree.jstree('show_contextmenu', ouId);
268 }, 100);
269 });
270
271 });
272 },
273
274 reload: function () {
275 vm.categoryTree.getTreeDataFromServer(function (treeData) {
276 vm.categoryTree.setUnitCount(treeData.length);
277 vm.categoryTree.$tree.jstree(true).settings.core.data = treeData;
278 vm.categoryTree.$tree.jstree('refresh');
279 });
280 }
281 };
288 //#endregion
289 vm.categoryTree.init();