MVC通过递归+部分视图实现评论

前一个项目里有一个关于评论系统的需求。感觉这个评论的实现还是蛮好玩的,所以记录下这个系统的实现相关内容。

 

能需求

1、用户可以再视屏下方留言。

2、用户可以再别的用户留言下方回复。

3、用户可以删除自己的留言,删除之后所有属于这个留言的子留言都会被删除。

 

 

分析:

看到上面这个需求的时候,想法是可以把这个留言内容作为一个“留言树”,一个留言就是一个根节点,然后留言下方的回复就是根节点下方的字节点。回复的回复就是子节点的子节点。

所以数据库的设计就要提现这几个要素:①父节点标记   ②本身节点标记   ③标记时间(用于区分两个兄弟节点谁先谁后)

 

 “SourseID”表示这个评论所属哪个课件资源。

接下来是树的生成了,主要的设计思路如下:

1、当需要课件A的评论树的时候,先从数据库中取出所有“SourseId”为课件A的评论数据,把上述数据放入队列Queue中,并定义一个空的树Tree

2、Queue出队一个数据D,数据D在Tree中通过递归逐层查询自己的父节点,如果找到父节点就在Tree相应位置插入数据D,如果没有找到就把D再入队Queue中。

3、重复2的操作,直至Queue空队

 

 

代码如下:

/// <summary>
        /// 获取页面视图所需要的评论树
        /// </summary>
        /// <returns></returns>
        public List<CommentTree> GetCommentsForView(int SourseId)
        {
            List<CommentTree> trees = new List<CommentTree>();
            List<CommentInfEntity> comments = dal.SelectCommentInfs($" AND C.SourseID ='{SourseId}'");
            Queue<CommentInfEntity> queues = new Queue<CommentInfEntity>(comments);
            while(queues.Count!=0)
            {
                CommentInfEntity c = queues.Dequeue();
                if (c.PId == 0)
                {
                    CommentTree tree = new CommentTree();
                    tree.Node = c;
                    tree.Branch = new List<CommentTree>();
                    trees.Add(tree);
                    trees = trees.OrderBy(x => x.Node.CommentTime).ToList();
                }
                else if (c.PId != 0)
                {
                    c.PName = comments.Where(x => x.Id == c.PId).FirstOrDefault().Name;
                    if (!ParentIsExist(trees,c))
                    {
                        queues.Enqueue(c);
                    }
                }
            }
            return trees;
        }
        /// <summary>
        /// 迭代修改
        /// </summary>
        /// <param name="trees"></param>
        /// <param name="queue"></param>
        /// <returns></returns>
        private bool ParentIsExist( List<CommentTree> trees, CommentInfEntity queue)
        {
            for(int i=0;i<trees.Count;i++)
            {
                if (trees[i].Node.Id == queue.PId)
                {
                    CommentTree t = new CommentTree();
                    t.Branch = new List<CommentTree>();
                    t.Node = queue;
                    trees[i].Branch.Add(t);
                    trees[i].Branch = trees[i].Branch.OrderBy(x => x.Node.CommentTime).ToList();
                    return true;
                }
                else
                {
                    if (ParentIsExist(trees[i].Branch, queue))
                    {
                        return true;
                    }
                }    
            }
            return false;
        }

这样子最后的Tree就获得了。

 

然后在视图里面就可以用Html.RenderPartial来显示了

@foreach (CommentTree tree in ViewBag.CommentInf)
                                        {
                                            <div class="weui-cell">
                                                <div class="weui-cell__hd"><i class="glyphicon glyphicon-user"></i></div>
                                                <div class="weui-cell__bd">
                                                    <p>@(tree.Node.Name):@(tree.Node.Comments)</p>
                                                </div>
                                                <div class="weui-cell__ft"><i commentname="@(tree.Node.Name)"  commentid="@(tree.Node.Id)" class="glyphicon   @(tree.Node.WeiXinPublicId == ViewBag.UserWeiXin ? "glyphicon-remove":"glyphicon-pencil")   " id="@(tree.Node.WeiXinPublicId == ViewBag.UserWeiXin ? "del-comment":"rep-comment")"></i></div>
                                            </div>
                                            foreach (var node in tree.Branch)
                                            {
                                                Html.RenderPartial("../Course/CommentParyial", node);
                                            }
                                        }

 

部分视图:

<div class="weui-cell reply">
    <div class="weui-cell__hd"><i class="glyphicon glyphicon-user"></i></div>
    <div class="weui-cell__bd">
        <p>@Model.Node.Name 回复 @Model.Node.PName:@Model.Node.Comments</p>
    </div>
    <div class="weui-cell__ft"><i commentname="@(Model.Node.Name)"  commentid="@(Model.Node.Id)"  class="glyphicon @(Model.Node.WeiXinPublicId == ViewBag.UserWeiXin ? "glyphicon-remove":"glyphicon-pencil")   "  id="@(Model.Node.WeiXinPublicId == ViewBag.UserWeiXin ? "del-comment":"rep-comment")"></i></div>
</div>

@foreach (var node in Model.Branch)
{
    Html.RenderPartial("../Course/CommentParyial", node);
}

 

上述部分视图也是用了递归的方法。

首先在页面上面显示根节点Node,然后把子节Child点发送给部分视图页面,部分视图页面获得数据后,把得到的子节Child点作为根节点显示,然后把Child的子节点发送给部分视图。。。。。最后直至数据结束,

 

posted @ 2017-07-07 15:23  陌陌秋雨  阅读(923)  评论(0编辑  收藏  举报