【连载】研究EasyUI系统—Tree组件(高级属性和用法)

来源:互联网 发布:知网有哪些数据库 编辑:程序博客网 时间:2024/05/18 17:54

  tree组件的基本用法已经在《研究EasyUI系统—Tree组件(基本属性和用法)》一文中介绍过(http://blog.csdn.net/redeg/article/details/70213557),此文主要介绍tree组件如何从已有的本地数据以及从远程服务器获取数据并动态构建树形结构的导航目录。
  我们先看一下如何加载本地数据来构造目录。

<html>    <head>        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">        <link rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css" />        <link rel="stylesheet" type="text/css" href="../easyui/themes/icon.css" />        <script type="text/javascript" src="../easyui/jquery.min.js"></script>        <script type="text/javascript" src="../easyui/jquery.easyui.min.js"></script>        <title>treeLocalDemo</title>    </head>    <body>        <div class="contianer">            <ul id="treeContainer" class="easyui-tree"></ul>        </div>        <script>            var treeData = [{                    "id": 1,                    "text":"人力资源部",                    "state":"open",                    "checked":true,                    "attributes":{"manager":"李明"}                },{                    "id": 2,                    "text":"企业信息化部",                    "state":"open",                    "checked":true                },{                    "id":3,                    "text":"总务部",                    "state":"open",                    "checked":false,                    "children":[{                        "id":4,                        "text":"法务处"                    },{                        "id":5,                        "text":"综合处"                    },{                        "id":6,                        "text":"后勤保障处"                    }]                },{                    "id":7,                    "text":"硬件事业部",                    "state":"open",                    "checked":false,                    "children":[{                        "id":8,                        "text":"传感器研发中心"                    },{                        "id":9,                        "text":"芯片研发中心"                    }]                },{                    "id":10,                    "text":"软件事业部",                    "state":"closed",                    "checked":false,                    "children":[{                        "id":11,                        "text":"负载均衡研发中心"                    },{                        "id":12,                        "text":"云计算研发中心"                    }]                }]            $(document).ready(function() {                $("#treeContainer").tree({                    checkbox:true,                    data:treeData,                    onClick:function(node) {                        alert(node.attributes.manager);                    }                });            });        </script>    </body></html>

本地数据加载效果图
  本地数据加载使用了data属性。data属性的值是json数组,数组包括了构造各级节点所需要的数据。节点的属性我们已经在《研究EasyUI系统—Tree组件(基本属性和用法)》一文中有过说明。
  在上例代码中,children属性也是json数组,它是当前节点下的子节点,可以一层一层深入下去,attributes属性允许开发者添加自定义的属性。例子代码中在“人力资源部”一项中添加“manager”自定义属性,并在onClick事件中获取该节点,显示该属性值。
  下面再介绍如何结合数据库,通过远程服务器获取数据动态构建目录。
  首先建立数据库表,结构和数据如下图。
数据库表
  parent_id字段表示父节点的id,parent_id为0则表示该节点为一级目录,无子节点。
  下面的代码展示了如何远程构造树形节点。
  treeServerDemo.php

<html>    <head>        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">        <link rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css" />        <link rel="stylesheet" type="text/css" href="easyui/themes/icon.css" />        <script type="text/javascript" src="easyui/jquery.min.js"></script>        <script type="text/javascript" src="easyui/jquery.easyui.min.js"></script>        <title>treeServerDemo</title>    </head>    <body>        <div class="contianer">            <ul id="treeContainer" class="easyui-tree"></ul>        </div>        <script>            $(document).ready(function(){                $("#treeContainer").tree({                    url:'getTreeNavData.php',                    method:"post",                    queryParams:{parent_id:0},                    onBeforeExpand:function(node) {                        //onBeforeExpand在二级目录展开前触发                        var target = node.target;                        // 获取要展开节点的子节点                        var children = $("#treeContainer").tree("getChildren",target);                        $.post("getTreeNavData.php",{parent_id:node.id},function(data){                            for(var i in children) {                                // 增加子节点前先删除原先有的子节点                                $("#treeContainer").tree("remove",children[i].target);                            }                            // 增加子节点                            $("#treeContainer").tree("append",{parent:target,data:data});                        },"json");                       // 此处返回false为了避免tree组件再次构造自己                       return false;                    }                });            });        </script>    </body></html>

  getTreeNavData.php

<?php/* * 本模块从数据库获取数据用于构造树形导航 */define ("DATABASE","mysql");define ("DATABASE_NAME","easyuidemo");define ("DATABASE_USER","root");define ("DATABASE_PASSWORD","12345");define("DATABASE_HOST","localhost");define ("DATABASE_TABLE_NAME", "treenavigation");define("DSN", DATABASE . ":" . "host=" . DATABASE_HOST . ";dbname=" . DATABASE_NAME . ";charset=utf8");header("Content-Type:text/html; charset=utf-8");date_default_timezone_set("Asia/Shanghai");/* parent_id表示父节点目录 */$parent_id = trim(filter_input(INPUT_POST, "parent_id"));if (!$parent_id) {    $parent_id = 0;}try {    /* 通过pdo来操作数据库 */    $db_pdo = new PDO(DSN, DATABASE_USER, DATABASE_PASSWORD);    $db_pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);    $result = array();    $sql = "SELECT * FROM treenavigation WHERE parent_id = $parent_id";    $stmt = $db_pdo->prepare($sql);    if (!$stmt || !$stmt->execute()) {        throw new Exception();    }    $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);    foreach ($rs as $value) {    /* 为每个节点建立属性数组 */        $node["id"] = $value["id"];        $node["text"] = $value["text"];        /* 查询该节点是否有子节点 */        $sql = "SELECT count(id) AS cid FROM treenavigation WHERE parent_id=" . $value["id"];        $stmt = $db_pdo->prepare($sql);        if (!$stmt || !$stmt->execute()) {            throw new Exception();        }        $tmp = $stmt->fetch(PDO::FETCH_ASSOC);        if ($tmp["cid"] == 0) {            $node['state'] = "open";        } else {            $node['state'] = "closed";        }        $result[] = $node;    }    echo json_encode($result);} catch (Exception $ex) {    echo "";}

  代码使用了组件的url等属性,请求getTreeNavData.php从数据库读取数据并返回。此外我们还使用了onBeforeExpand事件。因为我们首次从服务器中获取数据的时候,并非一次性将所有的节点都取回来,而是取所有的一级节点。当用户点击带有子节点的目录项时,触发onBeforeExpand事件,onBeforeExpand事件使用ajax中的$.post方法,再次调用getTreeNavData.php获取该节点下的所有子节点。
  queryParams属性表示请求服务器数据时传递的额外参数,类似于form表单中的字段值。这里传送的是父节点的id,值为0,表示一级节点。之后的$.post方法也传递了相同的参数,参数值则为对应一级节点的id。
  treeServerDemo.php在构造节点的时候,首先要删除原有的二级节点,避免展开一次就追加一组同样的数据。最后返回false,为的是避免tree组件构造自身,否则二级节点下面出现所有的一级节点,构造就会出错。
  有关《研究EasyUI系统—Tree组件(基本属性和用法)》一文中,tree组件还有formatter、loader、loadFilter三个属性未作说明,下面一一说明。
  formateer属性用于解析节点标题文本。它的属性值是一个方法,方法的参数是当前节点(node)。
  loader属性用于解析从远程服务器加载的数据。它的属性值也是一个方法,方法有三个参数,param、success、error。这个方法和ajax中的$.ajax是一样的。我们可以定义一个新的包含$.ajax方法的function来作为loader的属性值。这个属性不怎么会用到。
  loadFilter用于对数据的过滤,它的属性值同样是方法,方法含有参数data,表示节点的属性数据。
使用formatter属性后的效果图

<html>    <head>        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">        <link rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css" />        <link rel="stylesheet" type="text/css" href="easyui/themes/icon.css" />        <script type="text/javascript" src="easyui/jquery.min.js"></script>        <script type="text/javascript" src="easyui/jquery.easyui.min.js"></script>        <title>高级属性</title>    </head>    <body>        <div class="contianer">            <ul id="treeContainer" class="easyui-tree"></ul>        </div>        <script>            $(document).ready(function(){                $("#treeContainer").tree({                    url:'getTreeNavData.php',                    method:"post",                    queryParams:{parent_id:0},                    formatter:function(node) {                        if (node.state == "closed") {                            return node.text + "(可点击展开)";                        } else {                            return node.text;                        }                    }                });            });        </script>    </body></html>

  formatter属性中,我们对要显示的文本标题做了一个自定义处理,凡是有二级节点的,在其标题后面均加上“(可点击展开)”字样。

0 0
原创粉丝点击