最近在为公司开发一个在线浏览PDF文档的小web系统。在构建动态列表的时候犯了愁,很久没写代码了,手有些生了,搞了半天才搞出来,写篇博文记录一下。
首先是数据库设计
我设计的一个列数为三列的表Treenodes,这三列分别用来存储当前节点的id、节点名称、父节点
SQL如下
CREATE TABLE `treenodes` (
`id` int(11) NOT NULL,
`node_name` varchar(50) DEFAULT NULL,
`pid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
前台页面已经搭好。只要能构建形如下面的html代码,前台的js就能很好的展现树形列表了。
<ul>
<li>根节点
<ul>
<li>子节点1</li>
<li>子节点2
<ul>
<li>孙子节点1</li>
<li>孙子节点1</li>
</ul>
</li>
</ul>
</li>
</ul>
先放置一些测试数据供展现。
INSERT INTO `treenodes` VALUES ('1', 'INMIX 培训知识库', '-1');
INSERT INTO `treenodes` VALUES ('2', 'IT部门', '1');
INSERT INTO `treenodes` VALUES ('3', 'HR部门', '1');
INSERT INTO `treenodes` VALUES ('4', '线上培训', '1');
INSERT INTO `treenodes` VALUES ('5', '线下培训', '1');
INSERT INTO `treenodes` VALUES ('6', 'ERP系统方面 ', '2');
INSERT INTO `treenodes` VALUES ('7', '软件应用方面', '2');
INSERT INTO `treenodes` VALUES ('8', 'IT设备应用方面', '2');
INSERT INTO `treenodes` VALUES ('9', '店铺系统方面', '2');
INSERT INTO `treenodes` VALUES ('10', '钉钉轻松小秘书日程管理(V1.0).pdf', '6');
第一步先把数据从数据库中取出来
$conn = new mysqli('xxx.xxx.xxx.xxx', 'userxxx', 'xxxxxx', 'QuotationSystem');
/* check connnection */
if ($conn ->connect_errno){
printf("Connect failed: %s \n", $conn->connect_error);
exit();
}
if ($q = $conn ->query('select * from treenodes a')){
$result = $q-> fetch_all();
}
第二步是将数据存放在一个多维的数组里边
定义的数据结构是:
用数组来存放一个节点, 如果这个节点是末端节点,则该数组,只有一个字符串元素,
如果这个节点存在子节点,则在当前数组中,增加一个数组,所有的子节点的元素存放在这个数组中。
function build_book_tree($data, $parentid){
$nodeName = '';
$child = [];
foreach($data as $key => $val){
//如果当前遍历的项跟查询的id相同,则获取节点的名称
if ($val[0] == $parentid){
$nodeName = $val[1];
}
//如果当前节点的父节点跟查询的节点相同,则通过递归,获取他的子节点,并将结果,赋给当前节点节点数组中
if ($val[2] == $parentid){
array_push($child, build_book_tree($data, $val[0]));
}
}
//不存放空节点
if (count($child) > 0)
return array($nodeName, $child);
else
return $nodeName;
}
第三步 是生成html 列表元素, 这是我今天卡壳的地方。递归用的不太好,后来整理了一下思路,问题就迎刃而解了。
思路:先尝试把一个节点,拥有一个子节点的数据结构构建成html树。然后再构建复杂的情情况。函数只要实现<li>节点名<ul><li>子节点一</li>...</ul></li>就行了。递归函数只帮我们构建最简单的形式,赋予它更多的意义,实现起来困难程度就会加倍。 所有构建html树的实现应该是这样的:
function build_html_list($data)
{
if (is_array($data) and count($data) == 2 and is_string($data[0])){
// 输出节点名
echo "<li>".$data[0];
// 输出子节点
if (is_array($data[1])){
echo "<ul>";
foreach ($data[1] as $item){
if (is_string($item)){
echo "<li>".$item."</li>";
}
else{
build_html_list($item);
}
}
echo "</ul>";
}
echo "</li>";
}
// 输出单个元素的节点
else if (is_string($data)){
echo "<li>".$data."</li>";
}
}
输出它的时候,需要给上述方法添加“<ul>”html元素。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。