ThinkPHP结合Jquery实现无限级嵌套回复
blog程序出来这么久,一直为文章的嵌套回复困恼。主要由于ThinkPHP模板的缘故,无法使用PHP语言在页面直接生成嵌套内容。经过不断的度娘爬文,找到了个思路。
思路大概是,先从数据库中读取文章的所有回复,在ThinkPHP中对数组计算,形成一个树形结构。
以下是数据库结构:
每一条记录通过reply字段,跟他的父项目建立关联。使用递归的方法将子项加入父项目,直到最底层介绍,重新整理后通过JSON输出整个回复的树形结构。
以下为ThinkPHP处理回复的函数
/*返回经过处理过后Json,完成回复嵌套*/ public function findParentNode($array, $children, $parentId) { $length = sizeof($array); for ($i = 0; $i < $length; $i++) { if ($array[$i]['id'] == $parentId) { if ($array[$i]['children'] == NULL) { $array[$i]['children'] = array($children); //给每个有子项的父项加入一个children字段 } else { array_push($array[$i]['children'], $children); } return $array; } if (!empty($array)) { $array[$i]['children'] = $this->findParentNode($array[$i]['children'], $children, $parentId); //递归调用往下一层级遍历 } } return $array; } /*$id:文章id*/ public function getCommentsJson($id) { $model = M('comments'); $array = $model->where('archive=' . $id)->order('id asc')->select(); foreach ($array as $key => $value) { $value["children"] = 'children'; $array[$key]['email'] = getGravatar($array[$key]['email']); $array[$key]['children'] = array(); if ($value["reply"] != '0') { //判断是否为父项 $array_children = $array[$key]; $array = $this->findParentNode($array, $array_children, $value["reply"]); //将有子项的回复代入findParentNode } } //重新整理,讲数组根目录下,删除replyID的元素 $rtnArray = array(); $l = sizeof($array); for ($i = 0; $i < $l; $i++) { if ($array[$i]['reply'] == '0') { array_push($rtnArray, $array[$i]); } } print_r(json_encode($rtnArray)); } /*****************嵌套回复测试片段*****************************/
在前台模板中通过ajax请求ThinkPHP函数地址,并对json进行遍历根据层级输出。
comment.js
/*每条comment回复模板*/ var liTemplate = "<li class=\"comment-body comment-odd \" id=\"comment-{#commentId#}\" itemscope=\"\"><div class=\"comment-author\" itemprop=\"creator\"><span itemprop=\"image\"><img width=\"32\" height=\"32\" class=\"avatar\" alt=\"{#commentAuthor#}\" src=\"{#commentEmail#}\"></span><cite class=\"fn\" itemprop=\"name\"><a href=\"#\" id=\"author-41\" rel=\"external nofollow\">{#commentAuthor#}</a></cite></div><div class=\"comment-meta\"><a href=\"#comment-{#commentReply#}\"><time itemprop=\"commentTime\">{#commentTime#}</time></a></div><div class=\"comment-content\" itemprop=\"commentText\"><p>{#commentTxt#}</p></div><div class=\"comment-reply-{#commentId#}\"><a onclick=\"typechoCommentChild({#commentId#})\" href=\"#respond-post-1\" rel=\"nofollow\">回复</a></div></li>"; //获取js文件调用参数 var archiveId = document.getElementById('commentScript').getAttribute('archiveId'); var urlRoot = document.getElementById('commentScript').getAttribute('url'); function display(obj, dom, level) { var i = 0; var ol = $('<ol/>'); ol.addClass('comment-list comment-main'); while (i < obj.length) { var commentStr = liTemplate; //替换掉模板中的信息 commentStr = commentStr.replace(/{#commentId#}/g, obj[i]['id']); commentStr = commentStr.replace(/{#commentAuthor#}/g, obj[i]['author']); commentStr = commentStr.replace('{#commentTxt#}', obj[i]['comment']); commentStr = commentStr.replace('{#commentEmail#}', obj[i]['email']); commentStr = commentStr.replace(/{#commentTime#}/g, obj[i]['commtime']); commentStr = commentStr.replace(/{#commentReply#}/g, obj[i]['reply']); var dom_children = $(commentStr); if (level % 2 == 1) {//判断奇偶根据奇偶设置每个层级的class dom_children.addClass('comment-level-odd'); } else { dom_children.addClass('comment-level-even'); } ol.addClass('comment-parent-' + obj[i]['reply']); ol.append(dom_children); var childrenNode = obj[i]['children']; if (childrenNode != null) { level++; display(childrenNode, dom_children, level); level--; } if (childrenNode == null && i == obj.length - 1) { return; } i++; } if (level != 0) {//判断是否为根节点 ol.removeClass('comment-main'); var div = $('<div/>'); div.addClass('comment-children'); div.append(ol); ol = div; } dom.append(ol); } $.ajax({ type: 'get', url: urlRoot + '/index.php/home/index/getcommentsjson/id/' + archiveId, datatype: 'json', data: {}, success: function(data1) { var obj = eval('(' + data1 + ')'); var dom = $('#comments'); display(obj, dom, false); } });
具体实现效果请看本文回复。
有19条评论