这个问题仍是挺经典的,后台只是负责查出全部的数据,前台js来处理数据展现给treeview;show you the code below:<script> $(function () { getData(); }) var displaySeach = function(){ if($("#search-page .x_content").is(":hidden")) $('#search-page .x_content').slideDown(300); else $('#search-page .x_content').slideUp(300); } function getTree() { //节点上的数据遵循以下的格式: var tree = [{ text: "场地列表", //节点显示的文本值 string icon: "glyphicon glyphicon-play-circle", //节点上显示的图标,支持bootstrap的图标 string selectedIcon: "glyphicon glyphicon-ok", //节点被选中时显示的图标 string color: "#ff0000", //节点的前景色 string backColor: "#1606ec", //节点的背景色 string selectable: true, //标记节点是否能够选择。false表示节点应该做为扩展标题,不会触发选择事件。 string state: { //描述节点的初始状态 Object checked: true, //是否选中节点 /*disabled: true,*/ //是否禁用节点 expanded: true, //是否展开节点 selected: true //是否选中节点 } }] return tree; } function getData() { $.ajax({ type: "GET", url: "/serverPoint/index", success: function (data) { console.log("data", data); for (var k = 0; k < data.length; k++) { data[k]['text'] = data[k]['Name']; } var tree = [{ text: "场地列表", //节点显示的文本值 string icon: "glyphicon glyphicon-play-circle", //节点上显示的图标,支持bootstrap的图标 string selectedIcon: "glyphicon glyphicon-ok", //节点被选中时显示的图标 string color: "#ff0000", //节点的前景色 string backColor: "#1606ec", //节点的背景色 string selectable: true, //标记节点是否能够选择。false表示节点应该做为扩展标题,不会触发选择事件。 string state: { //描述节点的初始状态 Object checked: true, //是否选中节点 /*disabled: true,*/ //是否禁用节点 expanded: true, //是否展开节点 selected: true //是否选中节点 }, nodes: toTree(data) }] $('#tree').treeview({ data: tree,//节点数据 showBorder: true, //是否在节点周围显示边框 showCheckbox: true, //是否在节点上显示复选框 showIcon: true, //是否显示节点图标 highlightSelected: true, levels: 2, multiSelect: true, //是否能够同时选择多个节点 showTags: true }); }, error: function () { $.pnotify({ title: '失败提醒', text: '请求服务器失败', type: 'error', nonblock: { nonblock: false }, }); } }); } function toTree(data) { // 删除 全部 children,以防止屡次调用 data.forEach(function (item) { delete item.nodes; }); // 将数据存储为 以 id 为 KEY 的 map 索引数据列 var map = {}; data.forEach(function (item) { map[item.ID] = item; });// console.log(map); var val = []; data.forEach(function (item) { // 以当前遍历项,的pid,去map对象中找到索引的id var parent = map[item.ParentID]; // 好绕啊,若是找到索引,那么说明此项不在顶级当中,那么须要把此项添加到,他对应的父级中 if (parent) { (parent.nodes || (parent.nodes = [])).push(item); } else { //若是没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中,做为顶级 val.push(item); } }); return val; } $('.place-choice').on('change', function () { var cityNum = $(this).val(); console.log("cityNum:", cityNum); addPlaceSelect($(this), cityNum); }); var addPlaceSelect = function (obj, cityNum) { console.log("addPlaceSelect...................."); obj.nextAll().remove(); $.ajax({ url: '/serverPoint/getChild/' + cityNum, type: 'get', data: {}, success: function (data) { if (data) { if (data.length > 0) { console.log('data.length > 0'); var select = $('<select></select>'); select.addClass('select2_single form-control place-choice').css('margin-right', '5px').css('width', '100px').css('float', 'left'); $('.place-choice-td').append(select); select.on('change', function () { var cityNum = $(this).val(); addPlaceSelect($(this), cityNum); }); var str = '<option value="">请选择</option>'; select.append(str); for (var i = 0; i < data.length; i++) { var str = '<option value="' + data[i]['ID'] + '">' + data[i]['Name'] + '</option>'; select.append(str); } } } else { $.pnotify({ title: '失败提醒', text: '添加分类失败', type: 'error', nonblock: { nonblock: false }, }); } }, error: function () { $.pnotify({ title: '失败提醒', text: '请求服务器失败', type: 'error', nonblock: { nonblock: false }, }); } }); } function addNode(pid=null) { var parentId=''; if (pid == -1) { var text = $('#postition-name').val(); console.log('text:',text); parentId = 0; if (text == "" || text.length == 0) { $.pnotify({ title: '舒适提醒', text: '请先填写名称', type: 'error', nonblock: { nonblock: false }, }); return; } } else { parentId = $('.place-choice-td select:last-child').val(); console.log(parentId); var text = $('#sub-postition-name').val(); if (parentId == "" || parentId.length == 0) { $.pnotify({ title: '舒适提醒', text: '请先选择场景', type: 'error', nonblock: { nonblock: false }, }); return; } if (text == "" || text.length == 0) { $.pnotify({ title: '舒适提醒', text: '请先填写名称', type: 'error', nonblock: { nonblock: false }, }); return; } } $.ajax({ url: '/serverPoint/add', type: 'post', data: { 'parentId': parentId, 'name': text }, success: function (data) { $.pnotify({ title: '成功提醒', text: '添加成功', type: 'success', nonblock: { nonblock: false }, }); getData(); }, error: function () { $.pnotify({ title: '失败提醒', text: '请求服务器失败', type: 'error', nonblock: { nonblock: false }, }); } }); } /* function getTree() { //节点上的数据遵循以下的格式: var tree = [{ text: "Node 1", //节点显示的文本值 string icon: "glyphicon glyphicon-play-circle", //节点上显示的图标,支持bootstrap的图标 string selectedIcon: "glyphicon glyphicon-ok", //节点被选中时显示的图标 string color: "#ff0000", //节点的前景色 string backColor: "#1606ec", //节点的背景色 string href: "#http://www.baidu.com", //节点上的超连接 selectable: true, //标记节点是否能够选择。false表示节点应该做为扩展标题,不会触发选择事件。 string state: { //描述节点的初始状态 Object checked: true, //是否选中节点 /!*disabled: true,*!/ //是否禁用节点 expanded: true, //是否展开节点 selected: true //是否选中节点 }, //tags: ['标签信息1', '标签信息2'], //向节点的右侧添加附加信息(相似与boostrap的徽章) Array of Strings nodes: getData() }] return tree; }*/ /*function getData(){ $.ajax({ type: "GET", url: "/serverPoint/index", success:function(data){ console.log(JSON.stringify(data)); return JSON.stringify(data); }, error:function() { } }); }*/</script>