LayUI—tree樹形結(jié)構(gòu)的使用解析
樹形結(jié)構(gòu)在實(shí)際開發(fā)中很長用到,比如部門管理,權(quán)限菜單等。因?yàn)橛脴湫谓Y(jié)構(gòu)來展示會(huì)顯的很清晰明了。
最近寫了一個(gè)個(gè)人博客小項(xiàng)目中用到了LayUI的樹形結(jié)構(gòu),之后寫了一個(gè)小案例整理一下。
先看一下顯示的效果圖
點(diǎn)擊節(jié)點(diǎn)右面會(huì)顯示對(duì)應(yīng)部門的詳情信息,可以修改??梢宰远x按鈕添加部門,也可以直接用自帶的方法對(duì)部門進(jìn)行新增,修改和刪除??梢垣@取選中的節(jié)點(diǎn),根據(jù)項(xiàng)目需求(有的需要選中保存)。
先需要引入LayUI的樣式文件JS和CSS。
案例對(duì)應(yīng)的實(shí)體類Dept
@Entity public class Dept { private Integer id; private String name; //部門名稱 private String deptName; //部門負(fù)責(zé)人 private String phone; //電話號(hào) private String number; //編號(hào) private double idx; //排序 @JsonIgnore private Dept parent; @JsonIgnore private List<Dept> children = new ArrayList<>(); @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public double getIdx() { return idx; } public void setIdx(double idx) { this.idx = idx; } @ManyToOne @CreatedBy public Dept getParent() { return parent; } public void setParent(Dept parent) { this.parent = parent; } @OneToMany(cascade=CascadeType.ALL,mappedBy="parent") @OrderBy(value="idx") public List<Dept> getChildren() { return children; } public void setChildren(List<Dept> children) { this.children = children; } public Dept(Integer id, String name, String deptName, String phone, String number, double idx, Dept parent, List<Dept> children) { this.id = id; this.name = name; this.deptName = deptName; this.phone = phone; this.number = number; this.idx = idx; this.parent = parent; this.children = children; } public Dept(Integer id) { this.id = id; } public Dept() { } }
顯示LayUI樹形菜單,只需要一個(gè)標(biāo)簽容器即可。
<div id="dept_tree"> </div>
在案例中還有一些其他樣式,比如右邊的詳情信息,新增按鈕等。
完整代碼如下
<style type="text/css"> #dept_main, #dept_particulars{ width: 48.5%; display: inline-block; vertical-align: top; padding: 20px; background: white; box-sizing: border-box; } #dept_tree{ margin-top: 20px; } </style>
<div id="dept_main" style="margin-right: 2%;"> <fieldset class="layui-elem-field layui-field-title"> <legend>所有部門</legend> </fieldset> <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon"></i>添加部門</button> <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">獲取選中節(jié)點(diǎn)</button> <div id="dept_tree"> </div> </div> <div id="dept_particulars"> <fieldset class="layui-elem-field layui-field-title"> <legend>部門詳情</legend> </fieldset> <div id="dept_home"> <div class="layui-tree-emptyText">無數(shù)據(jù)</div> </div> </div>
JS請(qǐng)求數(shù)據(jù)渲染頁面代碼,data為請(qǐng)求數(shù)據(jù)源,當(dāng)時(shí)直接放入的請(qǐng)求鏈接,好像不行,所以之后才寫了一個(gè)方法去請(qǐng)求數(shù)據(jù)源。
layui.use(['tree', 'util'], function() { var tree = layui.tree; var util = layui.util; tree.render({ elem: '#dept_tree', data: getData(), id: 'treeId', showCheckbox: true, //是否顯示復(fù)選框 onlyIconControl: true }); }); function getData(){ var data = []; $.ajax({ url: "dept/treeload", //后臺(tái)數(shù)據(jù)請(qǐng)求地址 type: "post", async:false, success: function(resut){ data = resut; } }); return data; }
tree 組件提供的有以下基礎(chǔ)參數(shù),可根據(jù)需要進(jìn)行相應(yīng)的設(shè)置。
參數(shù)選項(xiàng) | 說明 | 類型 | 示例值 |
---|---|---|---|
elem | 指向容器選擇器 | String/Object | - |
data | 數(shù)據(jù)源 | Array | - |
id | 設(shè)定實(shí)例唯一索引,用于基礎(chǔ)方法傳參使用。 | String | - |
showCheckbox | 是否顯示復(fù)選框 | Boolean | false |
edit | 是否開啟節(jié)點(diǎn)的操作圖標(biāo)。默認(rèn) false。
| Boolean/Array | ['update', 'del'] |
accordion | 是否開啟手風(fēng)琴模式,默認(rèn) false | Boolean | false |
onlyIconControl | 是否僅允許節(jié)點(diǎn)左側(cè)圖標(biāo)控制展開收縮。默認(rèn) false(即點(diǎn)擊節(jié)點(diǎn)本身也可控制)。若為 true,則只能通過節(jié)點(diǎn)左側(cè)圖標(biāo)來展開收縮 | Boolean | false |
isJump | 是否允許點(diǎn)擊節(jié)點(diǎn)時(shí)彈出新窗口跳轉(zhuǎn)。默認(rèn) false,若開啟,需在節(jié)點(diǎn)數(shù)據(jù)中設(shè)定 link 參數(shù)(值為 url 格式) | Boolean | false |
showLine | 是否開啟連接線。默認(rèn) true,若設(shè)為 false,則節(jié)點(diǎn)左側(cè)出現(xiàn)三角圖標(biāo)。 | Boolean | true |
text | 自定義各類默認(rèn)文本,目前支持以下設(shè)定: text: { defaultNodeName: '未命名' //節(jié)點(diǎn)默認(rèn)名稱 ,none: '無數(shù)據(jù)' //數(shù)據(jù)為空時(shí)的提示文本 } | Object | - |
因?yàn)閠ree指定了json數(shù)據(jù)的鍵名稱,所以后臺(tái)傳遞過來的數(shù)據(jù)對(duì)應(yīng)的鍵名不一樣時(shí)需要做一下處理,或者實(shí)體類中的屬性名就和tree的JSON數(shù)據(jù)的鍵名稱一樣。
鍵名:
屬性選項(xiàng) | 說明 | 類型 | 示例值 |
---|---|---|---|
title | 節(jié)點(diǎn)標(biāo)題 | String | 未命名 |
id | 節(jié)點(diǎn)唯一索引,用于對(duì)指定節(jié)點(diǎn)進(jìn)行各類操作 | String/Number | 任意唯一的字符或數(shù)字 |
children | 子節(jié)點(diǎn)。支持設(shè)定選項(xiàng)同父節(jié)點(diǎn) | Array | [{title: '子節(jié)點(diǎn)1', id: '111'}] |
href | 點(diǎn)擊節(jié)點(diǎn)彈出新窗口對(duì)應(yīng)的 url。需開啟 isJump 參數(shù) | String | 任意 URL |
spread | 節(jié)點(diǎn)是否初始展開,默認(rèn) false | Boolean | true |
checked | 節(jié)點(diǎn)是否初始為選中狀態(tài)(如果開啟復(fù)選框的話),默認(rèn) false | Boolean | true |
disabled | 節(jié)點(diǎn)是否為禁用狀態(tài)。默認(rèn) false | Boolean | false |
后臺(tái)請(qǐng)求數(shù)據(jù)的方法。
@RequestMapping(value = "/treeload") @ResponseBody public Object treeload(){ Sort sort = Sort.by("idx"); List<Dept> dpet = deptService.findByParentIsNull(sort); //查找所有菜單 List<HashMap<String, Object>> result = new ArrayList<>(); //定義一個(gè)map處理json鍵名問題 return fun(dpet, result); } private Object fun(List<Dept> dpet, List<HashMap<String, Object>> result) { for(Dept d : dpet){ HashMap<String, Object> map = new HashMap<>(); map.put("id", d.getId()); map.put("title", d.getName()); map.put("spread", true); //設(shè)置是否展開 List<HashMap<String, Object>> result1 = new ArrayList<>(); List<Dept> children = d.getChildren(); //下級(jí)菜單 //這里可以根據(jù)自己需求判斷節(jié)點(diǎn)默認(rèn)選中 /*if(m.getParent() != null || m.getChildren().size() == 0){ map.put("checked", true); //設(shè)置為選中狀態(tài) }*/ map.put("children", fun(children, result1)); result.add(map); } return result; }
因?yàn)檫@里新建的實(shí)體類字段名和tree指定了json數(shù)據(jù)的鍵名稱不一樣,所以這里用了一個(gè)fun遞歸方法處理的。中間可以根據(jù)項(xiàng)目需求,根據(jù)條件判斷是否需要選中該節(jié)點(diǎn)。
返回的JSON數(shù)據(jù)格式
[ { "children": [ //子節(jié)點(diǎn) { "children": [ { "children": [], "id": 30, "title": "測(cè)試", "spread": true }, { "children": [], "id": 31, "title": "開發(fā)", "spread": true }, { "children": [ { "children": [], "id": 36, "title": "測(cè)試節(jié)點(diǎn)", "spread": true } ], "id": 32, "title": "測(cè)試", "spread": true } ], "id": 2, "title": "技術(shù)部", "spread": true }, { "children": [], "id": 19, "title": "財(cái)務(wù)部", "spread": true } ], "id": 1, //節(jié)點(diǎn)id "title": "某某公司", //節(jié)點(diǎn)名稱 "spread": true }, { "children": [], "id": 33, "title": "測(cè)試", "spread": true } ]
設(shè)置節(jié)點(diǎn)點(diǎn)擊回調(diào)方法(在加載數(shù)據(jù)方法tree.render中添加以下代碼)。
click: function (obj) { var id = obj.data.id; $("#dept_home").load("dept/show?id="+id); }
把請(qǐng)求過來的詳情頁面load到右邊的div中顯示。后臺(tái)請(qǐng)求方法
@RequestMapping(value = "/show") public void show(DeptForm form, ModelMap map) throws InstantiationException, IllegalAccessException { Dept model = new Dept(); Integer id = form.getId(); Integer parentId = 0; if(id!=null) { model = deptService.findById(id); parentId = model.getParent()==null?0:model.getParent().getId(); } map.put("parentId", parentId); map.put("model", model); }
DeptForm類為一個(gè)接收類,其中字段和實(shí)體類中一樣。根據(jù)請(qǐng)求傳遞過來的id,查詢這條數(shù)據(jù)的詳細(xì)信息,之后把查詢的當(dāng)前部門詳情數(shù)據(jù)及父級(jí)節(jié)點(diǎn)id(用于下拉樹TreeSelect)傳遞給詳情頁面。
show.html詳情頁面代碼。
<meta charset="UTF-8" /> <style type="text/css"> .myData .layui-form-item{ margin: 20px 100px 10px 45px; } .myData .layui-form-label{ width: 85px; } .layui-input-block { margin-left: 120px; } </style> <form class="layui-form myData" action="save" method="post" lay-filter="stuform"> <input type="hidden" name="id" data-th-value="${model.id}" /> <div class="layui-form-item"> <label class="layui-form-label">上級(jí)部門:</label> <div class="layui-input-block"> <input type="text" name="parentId" id="tree" lay-filter="tree" class="layui-input" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">部門名稱:</label> <div class="layui-input-block"> <input type="text" name="name" lay-verify="required" th:value="${model.name}" class="layui-input" /> </div> </div> <div class="layui-form-item" > <label class="layui-form-label">部門負(fù)責(zé)人:</label> <div class="layui-input-block"> <input type="text" name="deptName" th:value="${model.deptName}" class="layui-input" /> </div> </div> <div class="layui-form-item" > <label class="layui-form-label">電話:</label> <div class="layui-input-block"> <input type="text" name="phone" th:value="${model.phone}" class="layui-input" /> </div> </div> <div class="layui-form-item" > <label class="layui-form-label">編號(hào):</label> <div class="layui-input-block"> <input type="text" name="number" th:value="${model.number}" class="layui-input" /> </div> </div> <div class="layui-form-item" > <label class="layui-form-label">排序:</label> <div class="layui-input-block"> <input type="text" name="idx" value="0" th:value="${model.idx}" class="layui-input" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label"></label> <div class="layui-input-block"> <button lay-submit class="layui-btn layui-btn-radius layui-btn-normal" lay-filter="btnSub"> <i class="layui-icon"></i>修改并保存 </button> </div> </div> </form> <script th:inline="javascript"> layui.use(["treeSelect", "form", "tree"], function () { var form = layui.form; var tree = layui.tree; form.render('select'); var treeSelect = layui.treeSelect; treeSelect.render({ // 選擇器 elem: '#tree', // 數(shù)據(jù) data: 'dept/treeSelect?id='+[[${model.id==null ? 0 : model.id}]], // 異步加載方式:get/post,默認(rèn)get type: 'post', // 占位符 placeholder: '上級(jí)菜單', // 是否開啟搜索功能:true/false,默認(rèn)false search: true, // 一些可定制的樣式 style: { folder: { enable: true }, line: { enable: true } }, // 加載完成后的回調(diào)函數(shù) success: function (d) { // 選中節(jié)點(diǎn),根據(jù)id篩選 treeSelect.checkNode('tree', [[${model.parent == null? parentId: model.parent.id}]]); treeSelect.refresh('tree'); } }); form.on('submit(btnSub)', function (data) { $.post('dept/save', data.field, function (result) { if (result.success) { tree.reload('treeId', {data: getData()}); } layer.msg(result.msg, {offset: 'rb'}); }); return false; }); }); </script>
上級(jí)部門使用的是LayUI下拉樹顯示的,下拉樹數(shù)據(jù)請(qǐng)求方法。關(guān)于下拉樹的使用,可以訪問LayUI下拉樹TreeSelect的使用
@RequestMapping(value="/treeSelect") @ResponseBody public Object treeSelect(Integer id) { Sort sort = Sort.by("idx"); Specification<Dept> spec = buildSpec1(); List<Dept> list = deptService.findAll(spec,sort); return buildTree(list, id); } private Object buildTree(List<Dept> list, Integer id) { List<HashMap<String, Object>> result=new ArrayList<>(); for (Dept dept : list) { if(dept.getId() != id) { HashMap<String, Object> node=new HashMap<>(); node.put("id", dept.getId()); node.put("name",dept.getName()); node.put("open", false); node.put("checked", false); if(dept.getChildren().size() != 0) { node.put("children",buildTree(dept.getChildren(), id)); } result.add(node); } } return result; } public Specification<Dept> buildSpec1() { Specification<Dept> specification = new Specification<Dept>() { private static final long serialVersionUID = 1L; @Override public Predicate toPredicate(Root<Dept> root, CriteriaQuery<?> query, CriteriaBuilder cb) { HashSet<Predicate> rules=new HashSet<>(); Predicate parent = cb.isNull(root.get("parent")); rules.add(parent); return cb.and(rules.toArray(new Predicate[rules.size()])); } }; return specification; }
顯示的效果。
上面修改并保存后臺(tái)方法(因?yàn)樾薷暮托略龉灿玫囊粋€(gè)方法,用id區(qū)分的)。
@Override public Object save(DeptForm form) { try { Dept model = new Dept(); Integer id = form.getId(); if(id != null) { model = deptService.findById(id); } //父級(jí)菜單id Integer parentId = form.getParentId(); if(parentId == null) { model.setParent(null); }else { model.setParent(new Dept(parentId)); } BeanUtils.copyProperties(form, model,"id", "parent"); deptService.save(model); return new AjaxResult("數(shù)據(jù)保存成功!"); } catch (Exception e) { return new AjaxResult(false,"數(shù)據(jù)保存失敗"); } }
設(shè)置節(jié)點(diǎn)操作(在加載數(shù)據(jù)方法tree.render中添加以下代碼)。
edit: ['add', 'update', 'del'], //操作節(jié)點(diǎn)的圖標(biāo) operate: function(obj){ var type = obj.type; //得到操作類型:add、edit、del var data = obj.data; //得到當(dāng)前節(jié)點(diǎn)的數(shù)據(jù) var elem = obj.elem; //得到當(dāng)前節(jié)點(diǎn)元素 var id = data.id; var name = data.title; if(type === 'add'){ //增加節(jié)點(diǎn) $.post("dept/save", {parentId: id, name: "未命名"}, function (result) { tree.reload('treeId', {data: getData()}); }) //返回 key 值 return ; } else if(type === 'update'){ //修改節(jié)點(diǎn) $.post("dept/update", {id: id, name: name}, function () { tree.reload('treeId', {data: getData()}); }) } else if(type === 'del'){ //刪除節(jié)點(diǎn) $.post("dept/delete", {id: id}, function () { tree.reload('treeId', {data: getData()}); }); }; }
其中operate為操作節(jié)點(diǎn)回調(diào)方法。
obj.type為操作類型,add為新增,update為修改,edl為刪除。obj.data為操作節(jié)點(diǎn)后的數(shù)據(jù)。
新增節(jié)點(diǎn)后,向后臺(tái)發(fā)送請(qǐng)求添加節(jié)點(diǎn),save方法和上面修改方法一樣,id為新建節(jié)點(diǎn)的父級(jí)節(jié)點(diǎn)id。
修改節(jié)點(diǎn),同樣,向后臺(tái)發(fā)送修改請(qǐng)求,并傳遞對(duì)象的id,和修改后的數(shù)據(jù)作為參數(shù)。后臺(tái)響應(yīng)方法。
@RequestMapping(value = "/update") @ResponseBody public Object update(DeptForm form) { try { Dept model = deptService.findById(form.getId()); model.setName(form.getName()); deptService.save(model); return new AjaxResult("數(shù)據(jù)保存成功!"); } catch (Exception e) { return new AjaxResult(false,"數(shù)據(jù)保存失敗"); } }
刪除節(jié)點(diǎn)同理,傳遞刪除節(jié)點(diǎn)的id。刪除請(qǐng)求方法。
@RequestMapping(value="/delete") @ResponseBody public Object delete(Integer id) { try { deptService.deleteById(id); return new AjaxResult("數(shù)據(jù)刪除成功"); } catch (Exception e) { return new AjaxResult(false,"數(shù)據(jù)刪除失敗"); } }
使用按鈕操作樹形菜單。
現(xiàn)在頁面中定義兩個(gè)按鈕,給按鈕添加lay-demo=""屬性,并設(shè)置屬性值,JS通過這個(gè)屬性值,綁定點(diǎn)擊事件。
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon"></i>添加部門</button> <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">獲取選中節(jié)點(diǎn)</button>
綁定添加部門和獲取選中節(jié)點(diǎn)按鈕的點(diǎn)擊事件的JS代碼。
util.event('lay-demo', { addDept: function(othis){ $.get('dept/edit', function(data) { layer.open({ type: 1, title: '新增', area: ['530px'], content: data, btn: ['提交', '退出'], yes: function () { }, success: function (layero, index) { layui.use('form', function () { var form = layui.form; layero.addClass('layui-form'); var submitBtn = layero.find('.layui-layer-btn0'); submitBtn.attr('lay-filter', 'formVerify').attr('lay-submit', ''); layero.keydown(function (e) { if (e.keyCode == 13) { submitBtn.click(); } }); form.on('submit(formVerify)', function (data) { $.post('dept/save', data.field, function (result) { if (result.success) { layer.close(index); tree.reload('treeId', {data: getData()}); } layer.msg(result.msg, {offset: 'rb'}); }); return false; }); }); } }) }) }, gain: function () { var checkData = tree.getChecked('treeId'); var str = JSON.stringify(checkData); $.post('dept/checkedGain', {data: str}, function () { }); layer.alert(JSON.stringify(checkData), {shade:0}); } });
添加部門按鈕點(diǎn)擊事件,先發(fā)送請(qǐng)求到后臺(tái),跳轉(zhuǎn)到eidt新增頁面,edit.html新增頁面代碼,和上面的show.html顯示部門詳情頁面差不多。上級(jí)部門同樣使用的LayUI下拉樹顯示的,下拉樹數(shù)據(jù)請(qǐng)求方法,和上面的詳情頁面下拉樹請(qǐng)求方法一致。LayUI下拉樹TreeSelect的使用。新增后的保存方法也和上面的保存方法一致。
后臺(tái)請(qǐng)求方法代碼,跳轉(zhuǎn)到edit頁面。
@RequestMapping(value = "/edit") public void edit(){ }
edit.html頁面完整代碼如下。
<meta charset="UTF-8" /> <style type="text/css"> .myData .layui-form-item{ margin: 20px 100px 10px 45px; } .myData .layui-form-label{ width: 85px; } .layui-input-block { margin-left: 120px; } </style> <form class="layui-form myData" action="save" method="post" lay-filter="stuform"> <div class="layui-form-item"> <label class="layui-form-label">上級(jí)部門:</label> <div class="layui-input-block"> <input type="text" name="parentId" id="tree2" lay-filter="tree2" class="layui-input" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">部門名稱:</label> <div class="layui-input-block"> <input type="text" name="name" lay-verify="required" class="layui-input" /> </div> </div> <div class="layui-form-item" > <label class="layui-form-label">部門負(fù)責(zé)人:</label> <div class="layui-input-block"> <input type="text" name="deptName" class="layui-input" /> </div> </div> <div class="layui-form-item" > <label class="layui-form-label">電話:</label> <div class="layui-input-block"> <input type="text" name="phone" class="layui-input" /> </div> </div> <div class="layui-form-item" > <label class="layui-form-label">編號(hào):</label> <div class="layui-input-block"> <input type="text" name="number" class="layui-input" /> </div> </div> <div class="layui-form-item" > <label class="layui-form-label">排序:</label> <div class="layui-input-block"> <input type="text" name="idx" value="0" class="layui-input" /> </div> </div> </form> <script th:inline="javascript"> layui.use(["treeSelect", "form"], function () { var form = layui.form; form.render('select'); var treeSelect = layui.treeSelect; treeSelect.render({ // 選擇器 elem: '#tree2', // 數(shù)據(jù) data: 'dept/treeSelect', // 異步加載方式:get/post,默認(rèn)get type: 'post', // 占位符 placeholder: '上級(jí)菜單', // 是否開啟搜索功能:true/false,默認(rèn)false search: true, // 一些可定制的樣式 style: { folder: { enable: true }, line: { enable: true } }, // 加載完成后的回調(diào)函數(shù) success: function (d) { } }); }); </script>
頁面效果。
獲取選中節(jié)點(diǎn)按鈕點(diǎn)擊事件。如果項(xiàng)目需要保存數(shù)據(jù)時(shí),就需要獲取到選中節(jié)點(diǎn)的數(shù)據(jù)了。這里可以獲取到選中節(jié)點(diǎn)的數(shù)據(jù),之后當(dāng)參數(shù)傳遞到后臺(tái)。傳遞到后臺(tái)是一個(gè)JSON數(shù)據(jù)的字符串,需要轉(zhuǎn)換一下,這里給推薦大家兩個(gè)很好用的JSON轉(zhuǎn)換工具net.sf.json.JSONObject和Alibaba Fastjson。這里用的是Alibaba Fastjson,需要引入以下依賴。
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
這里用于輸出,新建了一個(gè)和tree的json數(shù)據(jù)的鍵名稱一樣的工具類DeptTree,代碼如下。
import java.util.ArrayList; import java.util.List; public class DeptTree { private Integer id; private String title; private boolean checked; private boolean spread; private List<DeptTree> children = new ArrayList<>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public List<DeptTree> getChildren() { return children; } public void setChildren(List<DeptTree> children) { this.children = children; } public boolean isChecked() { return checked; } public void setChecked(boolean checked) { this.checked = checked; } public boolean isSpread() { return spread; } public void setSpread(boolean spread) { this.spread = spread; } }
后臺(tái)接收到傳遞過來的JSON數(shù)據(jù)字符串,轉(zhuǎn)換后輸出方法。
@RequestMapping(value = "/checkedGain") @ResponseBody public void checkedGain(String data){ List<DeptTree> array2 = JSONArray.parseArray(data, DeptTree.class); treeData(array2); } //遞歸輸出選中數(shù)據(jù) private void treeData(List<DeptTree> array2) { for (DeptTree tree: array2){ System.out.println(tree.getTitle()+"==="+tree.getId()); if(tree.getChildren() != null){ treeData(tree.getChildren()); } } }
選中節(jié)點(diǎn),點(diǎn)擊獲取選中節(jié)點(diǎn)數(shù)據(jù)。
后臺(tái)對(duì)應(yīng)方法接收到數(shù)據(jù),轉(zhuǎn)換后輸出結(jié)果。
數(shù)據(jù)拿到了,之后保存方法就簡單了。
后臺(tái)方法代碼基本都在上面了,頁面全部代碼。
<style type="text/css"> #dept_main, #dept_particulars{ width: 48.5%; display: inline-block; vertical-align: top; padding: 20px; background: white; box-sizing: border-box; } #dept_tree{ margin-top: 20px; } </style> <div id="dept_main" style="margin-right: 2%;"> <fieldset class="layui-elem-field layui-field-title"> <legend>所有部門</legend> </fieldset> <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon"></i>添加部門</button> <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">獲取選中節(jié)點(diǎn)</button> <div id="dept_tree"> </div> </div> <div id="dept_particulars"> <fieldset class="layui-elem-field layui-field-title"> <legend>部門詳情</legend> </fieldset> <div id="dept_home"> <div class="layui-tree-emptyText">無數(shù)據(jù)</div> </div> </div> <script type="text/javascript"> layui.use(['tree', 'util', 'layer'], function() { var tree = layui.tree; var util = layui.util; var layer = layui.layer; tree.render({ elem: '#dept_tree', data: getData(), id: 'treeId', showCheckbox: true, //時(shí)候顯示復(fù)選框 onlyIconControl: true, edit: ['add', 'update', 'del'], //操作節(jié)點(diǎn)的圖標(biāo) click: function (obj) { var id = obj.data.id; $("#dept_home").load("dept/show?id="+id); }, operate: function(obj){ var type = obj.type; //得到操作類型:add、edit、del var data = obj.data; //得到當(dāng)前節(jié)點(diǎn)的數(shù)據(jù) var elem = obj.elem; //得到當(dāng)前節(jié)點(diǎn)元素 var id = data.id; var name = data.title; if(type === 'add'){ //增加節(jié)點(diǎn) $.post("dept/save", {parentId: id, name: "未命名"}, function (result) { tree.reload('treeId', {data: getData()}); }) //返回 key 值 return ; } else if(type === 'update'){ //修改節(jié)點(diǎn) $.post("dept/update", {id: id, name: name}, function () { tree.reload('treeId', {data: getData()}); }) } else if(type === 'del'){ //刪除節(jié)點(diǎn) $.post("dept/delete", {id: id}, function () { tree.reload('treeId', {data: getData()}); }); }; } }); util.event('lay-demo', { addDept: function(othis){ $.get('dept/edit', function(data) { layer.open({ type: 1, title: '新增', area: ['530px'], content: data, btn: ['提交', '退出'], yes: function () { }, success: function (layero, index) { layui.use('form', function () { var form = layui.form; layero.addClass('layui-form'); var submitBtn = layero.find('.layui-layer-btn0'); submitBtn.attr('lay-filter', 'formVerify').attr('lay-submit', ''); layero.keydown(function (e) { if (e.keyCode == 13) { submitBtn.click(); } }); form.on('submit(formVerify)', function (data) { $.post('dept/save', data.field, function (result) { if (result.success) { layer.close(index); tree.reload('treeId', {data: getData()}); } layer.msg(result.msg, {offset: 'rb'}); }); return false; }); }); } }) }) }, gain: function () { var checkData = tree.getChecked('treeId'); var str = JSON.stringify(checkData); $.post('dept/checkedGain', {data: str}, function () { }); layer.alert(JSON.stringify(checkData), {shade:0}); } }); }); function getData(){ var data = []; $.ajax({ url: "dept/treeload", //后臺(tái)數(shù)據(jù)請(qǐng)求地址 type: "post", async:false, success: function(resut){ data = resut; } }); return data; } </script>
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用mpvue搭建一個(gè)初始小程序及項(xiàng)目配置方法
這篇文章主要介紹了使用mpvue搭建一個(gè)初始小程序及項(xiàng)目配置方法,需要的朋友可以參考下2018-12-12javascript 具名函數(shù)的四種調(diào)用方式 推薦
看四種方式執(zhí)行結(jié)果沒有區(qū)別。但如果函數(shù)有返回值的話,用new方式調(diào)用時(shí)可能會(huì)讓你有些失望。2009-07-07