web页面 之 评论盖楼

一、前言

  评论是人与人之间,在网络上交互的一个重中之重的窗口,这在前端当中也算是一个不可或缺的模块!

  我们浏览各种能吐槽,能刷人气的网站,在各种头条的下面,都有评论这一项!我们围观水军吐槽的时候会发现,他们的评论楼有的是特别有层次感,一眼忘穿秋水知道怎么个评论大法,而有的设计的是一楼一楼的盖起来,要评论别人也是盖一层!简直是没有耐心去观战!估计是他们的前端想草草了事,整了个这么友好性近乎为零的评论楼,看的时候作为看官的我,想咂电脑的心都有。所以今天我们就简单的聊聊层次分明的盖楼方法!

二、原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#我们前提规定评论的内容都存在数据库里,字段与下面字典中的key一致!当我们从数据库中取出数据,然后实现评论楼!
#从数据库中以字典类型读取到数据,这些数据存放在一个列表里,对这个列表进行循环,先为每个字典加入一对键值对"'child':[]",判断每个字典中的父ID是否有值,
#没值证明是鼻祖,有值就找到对应的父ID,把自己加入到其孩子键为"child"所对应的列表里,依次类推对所有的数据进行一次整理!
 
#数据库获取到的数据
msg_list = [
    {'id':1,'content':'xxx','parent_id':None},
    {'id':2,'content':'xxx','parent_id':None},
    {'id':3,'content':'xxx','parent_id':None},
    {'id':4,'content':'xxx','parent_id':1},
    {'id':5,'content':'xxx','parent_id':4},
    {'id':6,'content':'xxx','parent_id':2},
    {'id':7,'content':'xxx','parent_id':5},
    {'id':8,'content':'xxx','parent_id':3},
]
 
"""
数据重新整合之后,按照我们的逻辑得到的数据
msg_list = [
        {
            'id':1,'content':'xxx',parent_id:None,child:[
                {'id':4,'content':'xxx',parent_id:1},
                {'id':5,'content':'xxx',parent_id:1,child:[
                    {'id':7,'content':'xxx',parent_id:5},
                ]}]
            },
            {'id':2,'content':'xxx',parent_id:None,child:[
                {'id':6,'content':'xxx',parent_id:2},
            ]},
            {'id':3,'content':'xxx',parent_id:None,child:[
                {'id':8,'content':'xxx',parent_id:3},
            ]},
    ]
"""
"""
最终效果展示:
    评论1
        评论4
            评论6
        评论5
    评论2
    评论3
"""
 
针对这种显示方式,我们有两种方法:
    一种是在服务端这边,通过函数做好数据的整合然后处理成要显示的效果的HTML标签字符串,然后发送给客户端;
    另一种是把整合好的数据发送给客户端,让客户端去实现最终显示的效果!
由于有子父ID判断的问题,需要用到递归函数,递归函数的弊端就是执行慢,严重占用机器的性能!如果是多人次的访问就会给服务器带来很大的压力;
而把数据传递到客户哪里,让客户的页面通过JS实现最终显示,虽然是把递归放到了客户端上,但是从全局上讲客户端仅仅是处理这个递归函数,而服务端仅是一个数据整合的功能,会大大提交服务器的效率!
     
#按照这个重新整合出来的已经分好等级的数据,通过父ID和child进行整理拼接,在页面上实现有层级的评论楼!
#python里面的apend之类的东西都是引用的原来数据的内从地址,对原数据进行操作的话
#我们引用的数据也会发生一样的变化(字典列表之类的)
  
#浙江吴彦祖的方法:
# for i in msg_list:
#     i['child']=[]
# for i in range(len(msg_list)-1,-1,-1):
#     if msg_list[i]['parent_id']:
#         msg_list[msg_list[i]['parent_id'] - 1]['child'].append(msg_list[i])
# new_msg_list = [i for i in msg_list if i['parent_id'] is None]
# print(new_msg_list)
  
#老师讲的方法
# v=[row.setdefault('child',[]) for row in msg_list] #这和地下的第一个for循环的作用是一样的,给每一个元素加一个'child':[]
# print(msg_list)
#如果我们想加快索引(快点找到数据的话)就建一个字典的数据结构,这是因为字典中的key会以一种特殊方式存于内存之中,他这种结构就是为了方便查找对应的值!
msg_list_dict={} #加快索引,节省时间
for item in msg_list:
    item['child']=[]
    msg_list_dict[item['id']]=item #字典中key为item['id'],value为item
    #把字典数据结构填上数据,能够加快索引,而且我们数据还是占得原来的内从空间
    #我们只是引用了数据的内容空间,所以不存在新的数据结构浪费空间一说
result=[]
for item in msg_list:
    pid=item['parent_id']
    if pid: #如果parent_id不为空,说明它是子级,要把自己加入对应的父级
        msg_list_dict[pid]['child'].append(item)
    else: #如果为空,说明他是父级,鼻祖级别,要把它单独立出来用
        result.append(item)
#result就是我们最终要的结果,因为这里面全是引用,所有数据的内存地址都没有变
#只不过被多个数据结构引用了而已
print(result)

三、精简版本

Django app中---->views.py函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def comments(request,nid):
    """
        评论
    :param request:
    :param nid:
    :return:
    """
    ret = {"status":True,"data":None,"msg":None}#定义初始值
    try:
        msg_list = models.Comment.objects.values("nid","article_id","content","create_time","reply_id","user_id")
        msg_list_dict = {}  # 定义一个字典
        for item in msg_list:
            item["child"] = []  # 给列表中的每个字典添加一对键值对 "child"=[]
            msg_list_dict[item["nid"]] = item  # 把数据重组成一个新的字典,以id为key,原字典为values
 
        result = []  # 定义一个新列表
        for item in msg_list:
            pid = item["reply_id"# 父id
            if pid:  # 如果父id存在的话
                msg_list_dict[pid]["child"].append(item)  # 就从新字典中为id为父id的child添加值
            else:
                result.append(item)  # 否则的话,就把对应的字典添加到新列表中(列表信息重组,把重复的值去掉)。
        ret["data"] = result
    except Exception as e:
       ret["status"] = False
       ret["msg"] = str(e)
    return HttpResponse(json.dumps(ret))

Django 中模版 HTML代码:

1
2
3
4
5
6
7
8
9
10
11
//我就是尝试着加了个框,和能看到位置手写的值
<div class="comments">
        <div></div>
        <div class="coms_head">评论列表</div>
        <div class="coms_body">
            <div class="coms_items_title">#1楼</div>
            <div></div>
            <div class="coms_items_info">你猜我写的啥?</div>
            <div id="commentArea"></div>
        </div>
</div>

重点来啦!JS实现多级评论:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<script type="text/javascript" src="/static/js/jquery-3.2.1.js"></script>
<script>
    $(function(){
        $.ajax({
            url:"/comments-{{ articles.nid }}.html",
            type:"GET",   //以GET方式获取数据
            dataType:"JSON",
            success:function(arg){
                if(arg.status){
                    var comment = commentTree(arg.data);
                    $("#commentArea").append(comment);
                } else{
                    alert(arg.msg);
                }
            }
        })
    });
    //自定义字符串格式化的方法(有一张博客里写过!)
    String.prototype.Format = function(arg){
        var temp = this.replace(/\{(\w+)\}/g,function(k,kk){
            return arg[kk];
        });
        return temp;
    };
    //简单实现评论楼的功能,通过递归判断信息中有没有child项,以实现主评论和子评论之间有层次关系
    function commentTree(commentList){
        var comment_str = "<div class='comment' >";
        $.each(commentList,function(k,row){
            var temps = "<div class='content'>{content}</div>".Format({"content":row.content});
            comment_str += temps;
            if (row.child.length>0){
                comment_str +=commentTree(row.child);
            }
        });
        comment_str += "</div>";
        return comment_str;
    }
</script>

必不可少的路由:

1
url(r'^comments-(\w+).html$',views.comments),

 

posted @   细雨蓝枫  阅读(483)  评论(0编辑  收藏  举报
编辑推荐:
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
阅读排行:
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
· 用 DeepSeek 给对象做个网站,她一定感动坏了
· .NET 8.0 + Linux 香橙派,实现高效的 IoT 数据采集与控制解决方案
· .NET中 泛型 + 依赖注入 的实现与应用
点击右上角即可分享
微信分享提示