bootstrap-tree view是一款非常好用的插件,它可以添加任意多层节点,效果如下所示:

使用之前需要在HTML页面添加依赖文件:

<link href="bootstrap.css" rel="stylesheet">
<script src="jquery.js"></script>
<script src="bootstrap-treeview.js"></script>

它的树结构如下所示:

var tree = [

  {
    text:"Parent 1",
    nodes: [
      {
        text:"Child 1",
        nodes: [
          {
            text:"Grandchild 1"
          },
          {
            text:"Grandchild 2"
          }
        ]
      },
      {
        text:"Child 2"
      }
    ]
  },
  {
    text:"Parent 2"
  }

]; 

text参数是必选项,当然你还可以根据实际需要添加其他参数,如下图所示,这是我项目中遇到的一个需要展示的部分树结构。。

[
{
"id": 33,
"text": "书籍\/杂志\/报纸",
"nodes":[
{
"id": 50004788,
"text": "工业\/农业技术",
"nodes": [
{
"id": 50004956,
"text": "交通\/运输"
},
{
"id": 50004782,
"text": "农业",
"nodes": [
{
"id": 50004786,
"text": "农业基础科学"
},
{
"id": 50004787,
"text": "园艺"
},
{
"id": 50004785,
"text": "林业"
},
{
"id": 50004784,
"text": "渔业"
},
{
"id": 50004783,
"text": "畜牧\/养殖"
}
]
}
     ]
    }
  ]
 }
]

这个树有四层,实际展示效果如下:

刚开始因为我之前做过一些基础工作,这些结构我都有,所以我手动地按照tree view要求的结构构造了我的json文件,但我要在前端页面展示出来,因此我还要读取json文件,再把它封装一下传到前端。。。。这个过程费了我老大的劲了。。。。。真的是,最初为了省事,结果最后越来越麻烦。。。下面我将我这个费劲的过程记录一下。不过这样也是有好处的,比如树结构是固定不变的,就可以采用这个方法。

首先是读取文件,此处要注意字符问题,如果代码中有中文,一定要注意在读文件的过程中要设置字符编码。

 1 String cateList = "";
2 try {
3 String url = Thread.currentThread().getContextClassLoader().getResource("xx.json").getFile();
4 FileInputStream fis = new FileInputStream(url);
5 InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
6 br = new BufferedReader(isr);
7 String tempString = null;
8 StringBuilder sb = new StringBuilder();
9 while ((tempString = br.readLine()) != null) {
10 sb.append(tempString);
11 }
12 cateList = sb.toString();
13 }catch (IOException e){
14 e.printStackTrace();
15 }

这里我先将xx.json按行读取,存放到cateList中,然后开始进行json的转换

 1         JSONArray jsonArray = JSONArray.fromObject(cateList);       //将读取的数据转换为JSONArray
2 Map<String, JSONObject> map_parent = new HashMap<>(); //存放最外层数组
3 Map<String, JSONObject> map = new HashMap<>(); //第二层
4 Map<String, JSONObject> map_child = new HashMap<>(); //第三层
5 Map<String, JSONObject> map_grandchild = new HashMap<>(); //第四层
6 for (int i = 0; i < jsonArray.size(); i++) {
7 CategoryNode node_parent = new CategoryNode();
8 JSONObject jsonObject = jsonArray.getJSONObject(i);
9 node_parent.setId(jsonObject.getInt("id"));
10 node_parent.setText(jsonObject.getString("text"));
11 if(jsonObject.has("nodes")){
12 JSONArray nodes = jsonObject.getJSONArray("nodes");
13 CategoryNode node = new CategoryNode();
14 for(int j=0; j<nodes.size(); j++){
15 if(nodes.getJSONObject(j).has("nodes")){
16 JSONArray nodes_child = nodes.getJSONObject(j).getJSONArray("nodes");
17 CategoryNode node_child = new CategoryNode();
18 node_child.setId(nodes.getJSONObject(j).getInt("id"));
19 node_child.setText(nodes.getJSONObject(j).getString("text"));
20 node_child.setNodes(nodes_child);
21 String cid_child = String.valueOf(nodes.getJSONObject(j).getInt("id"));
22 JSONObject json_child = JSONObject.fromObject(node_child);
23 map_child.put(cid_child, json_child);
24 for(int k=0; k<nodes_child.size(); k++){
25 if(nodes_child.getJSONObject(k).has("nodes")) {
26 JSONArray nodes_grandchild = nodes_child.getJSONObject(k).getJSONArray("nodes");
27 CategoryNode node_grandchild = new CategoryNode();
28 node_grandchild.setId(nodes_child.getJSONObject(k).getInt("id"));
29 node_grandchild.setText(nodes_child.getJSONObject(k).getString("text"));
30 node_grandchild.setNodes(nodes_grandchild);
31 String cid_grandchild = String.valueOf(nodes_child.getJSONObject(k).getInt("id"));
32 JSONObject json = JSONObject.fromObject(node_grandchild);
33 map_grandchild.put(cid_grandchild, json);
34 }
35 }
36 }
37 node.setId(nodes.getJSONObject(i).getInt("id"));
38 node.setText(nodes.getJSONObject(i).getString("text"));
39 node.setNodes(nodes.getJSONObject(i).getJSONArray("nodes"));
40 String cid_child = String.valueOf(nodes.getJSONObject(i).getInt("id"));
41 JSONObject json = JSONObject.fromObject(node);
42 map.put(cid_child, json);
43 }
44 node_parent.setNodes(jsonObject.getJSONArray("nodes"));
45 JSONObject json = JSONObject.fromObject(node_parent);
46 String cid = String.valueOf(node_parent.id);
47 map_parent.put(cid, json);
48 }else{
49 JSONObject json = JSONObject.fromObject(node_parent);
50 String id = String.valueOf(node_parent.id);
51 map_parent.put(id, json);
52 }
53 }

上面两块代码就是我从json文件取数据并将数据构造成传到前端使js能够解析的数据的过程。。。。CategoryNode是我自己构造的bean,里面是这棵树的参数的定义以及get,set方法。

重点来了~~下面我要讲的是我通过调用接口动态获取json文件需要的信息,并将这些信息按照tree view的格式构造的过程。。。。我的json结构里面包含了id,text,nodes,其中nodes是一个JSONArray,整棵树其实就是一个大的nodes包含了数个小的nodes。因此就需要用到递归,因为是多层结构,且节点不确定是否是孩子节点,我们需要判断,然后使用递归继续调用。。。代码如下:

 1 private List uploadCat(Long pid){
2 TaobaoClient client = new DefaultTaobaoClient(SERVER_URL, APP_KEY, SECRET);
3 ItemcatsGetRequest req = new ItemcatsGetRequest();
4 req.setFields("cid,name,is_parent");
5 req.setParentCid(pid);
6 JSONArray cat = new JSONArray();
7 List<Map> list = new ArrayList<>();
8 try {
9 ItemcatsGetResponse rsp = client.execute(req);
10 JSONObject body = JSONObject.fromObject(rsp.getBody());
11 //下面这行是获取接口返回的信息,item_cat是一个JSONArray
12 cat = body.getJSONObject("itemcats_get_response").getJSONObject("item_cats").getJSONArray("item_cat");
13
14 for(int i=0; i<cat.size(); i++){
15 Map map = new HashMap();
16 JSONObject json = new JSONObject();
17 boolean flag = (boolean) cat.getJSONObject(i).get("is_parent");
18 //判断是否是父节点,如果是父节点,那么就要给它构造一个nodes
19 if(flag){
20 map.put("text", cat.getJSONObject(i).getString("name"));
21 cid = cat.getJSONObject(i).getInt("cid");
22 map.put("id", cid);
23 pid = new Long((long) cid);
24 map.put("nodes", uploadCat(pid)); //这里是递归调用
25 json = JSONObject.fromObject(map);
26 }else{
27 map.put("text", cat.getJSONObject(i).getString("name"));
28 cid = cat.getJSONObject(i).getInt("cid");
29 map.put("id", cid);
30 json = JSONObject.fromObject(map);
31 }
32 list.add(json);
33 }
34 }catch (ApiException e){
35 e.printStackTrace();
36 }
37 return list;
38 }

最后通过servlet的一些处理,使这棵树能够传到前端页面展示。。。

前端js中加载树:

 1 $("#tmallTree").treeview({
2 data: data.result, //后台传过来的树
3 selectedBackColor:"#78A5F1", //设置选中节点的颜色
4 highlightSelected: true, //选中节点时高亮显示
5 onhoverColor: "#DFF1FB", //鼠标滑过时节点颜色
6 //下面的代码是设置点击时不用特意点那个“+”号,而是点击整个li标签也可以展开节点
7 onNodeSelected: function(event, data) {
8 if(data.nodes!=null){
9 var select_node = $('#tmallTree').treeview('getSelected');
10 if(select_node[0].state.expanded){
11 $('#tmallTree').treeview('collapseNode',select_node);
12 select_node[0].state.selected=false;
13 }
14 else{
15 $('#tmallTree').treeview('expandNode',select_node);
16 select_node[0].state.selected=false;
17 }
18 }else{
19 //获取选中节点的id
20 node = $("#tmallTree").treeview('getSelected')[0].id;
21 }
22 }
23 });

最后页面展示出来的效果就如前面的图所示。。。大功告成~~~


多层json的构造,取值,还有使用bootstrap的tree view在前端展示的相关问题的更多相关文章

  1. ZT: C#不建类直接Json解析与取值

    C#不建类直接Json解析与取值 2017年10月19日 15:58:22 圆圆娃哈哈 阅读数:701    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn. ...

  2. SNF快速开发平台MVC-EasyUI3.9之-WebApi和MVC-controller层接收的json字符串的取值方法和调用后台服务方法

    最近项目组很多人问我,从前台页面传到后台controller控制层或者WebApi 时如何取值和运算操作. 今天就都大家一个在框架内一个取值技巧 前台JS调用代码: 1.下面是选中一行数据后右键点击时 ...

  3. jmeter 导入csv数据中json格式数据取值不完整

    1.jmeter中添加csv数据文件时,数据是json格式 2.jmeter中执行取值发现只取了一部分 分析原因,json格式数据,中间有逗号,而csv是根据逗号来分割的,这回导致我们取值错位. 解决 ...

  4. Json数组对象取值

    1.数据格式 {"data":[{"username":"xxx","avatar":"xxx",& ...

  5. 对一个 复杂的json结果进行取值的例子

    1 JSON结果集 [ { "J_LP_OPERATE_MAIN": { "ID": "1900036295", "FILL_MA ...

  6. javascript中json对象json数组json字符串互转及取值

    今天用到了json数组和json对象和json类型字符串之间互转及取值,记录一下: 1.json类型的字符串转换为json对象及取值 var jsonString = '{"bar" ...

  7. 二、postman断言及正则表达式取值

    postman老式断言与新式断言总结:本文以微信开发者文档为例 断言处如图所示 一.老式断言 老式断言总结:var variables相当于代码中定义的变量,test['']=true;相当于pyth ...

  8. Jquery常用操作:checkbox、select取值,radio、checkbox、select选中及其相关

    常用Jquery操作:checkbox取值.select取值.radio选中.checkbox选中.select选中及其相关: 1.影藏页面元素 使用jquery真的很方便,比如要控制div的显示与隐 ...

  9. jsp页面获取参数的方法(url解析、el表达式赋值、session取值)【原创】

    最近使用myEclispse做网站,使用jsp+js+css做页面,网站中常用到从列表进入详情页面的跳转,下面对详情页面的值填充方式做一个简单总结: 1.url中使用request获取参数 jsp上方 ...

随机推荐

  1. [Swift]LeetCode676. 实现一个魔法字典 | Implement Magic Dictionary

    Implement a magic directory with buildDict, and search methods. For the method buildDict, you'll be ...

  2. Linux 下源码编译FFMEG

    目录 1. 安装依赖关系 2. 源码安装 yasm 3. 源码安装 NASM 4. 源码安装libx264 5. 源码安装x265 6. 源码安装 libmp3lame 7. 源码安装 libopus ...

  3. 机器学习基石笔记:04 Feasibility of Learning

    原文地址:https://www.jianshu.com/p/f2f4d509060e 机器学习是设计算法\(A\),在假设集合\(H\)里,根据给定数据集\(D\),选出与实际模式\(f\)最为相近 ...

  4. scala用ssh2连接Linux

    这个需要安装库: import ch.ethz.ssh2.{Connection, Session, StreamGobbler} 首先用 ip 和 post 创建连接: val conn: Conn ...

  5. 【Docker】(4)搭建私有镜像仓库

    [Docker](4)搭建私有镜像仓库 说明 1. 这里是通过阿里云,搭建Docker私有镜像仓库. 2. 这里打包的镜像是从官网拉下来的,并不是自己项目创建的新镜像,主要测试功能 一.搭建过程 首先 ...

  6. springBoot(12)---整合Swagger2

    Spingboot整合Swagger2 随着互联网技术的发展,一般开发都是前后端分离,那么前端和后端的唯一联系,变成了API接口:API文档变成了前后端开发人员联系的纽带,变得越来越重要,没有API ...

  7. Spring RestTemplate中几种常见的请求方式

    https://github.com/lenve/SimpleSpringCloud/tree/master/RestTemplate在Spring Cloud中服务的发现与消费一文中,当我们从服务消 ...

  8. MySQL系列--2.常用的命令

    1 .创建数据库 #语法: CREATE DATABASE dbName; #创建数据库rms create database rms; 2.切换数据库 #选择数据库 USE dbName; #选择数 ...

  9. Asp.Net SignalR GlobalHost外部通知

    GlobalHost 外部通知 之前都是在集线器类中进行服务器对客户端的通知操作,但是在开发中往往会有需求监控某个系统 ,比如OA系统  上级领导在上面宣布下午两点要开会 那么就要通知到其他的人.这里 ...

  10. NSCTF web200

    Topic Link http://ctf5.shiyanbar.com/web/web200.jpg 1) 分析代码可知a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQ ...