blog项目 评论楼【评论树升级版】

 

url路由配置:

url(r'^comment',views.comment),

 

 

views视图函数:

 1 def comment(request):
 2     content = request.POST.get('content')
 3     article_id = request.POST.get('article_id')
 4     user_id = request.user.pk
 5     pidd = request.POST.get('pd')
 6     if pidd:  # 子评论
 7         comment = Comment.objects.create(content=content, article_id=article_id, user_id=user_id, parent_comment_id=pidd)
 8     else:  # 根评论
 9         comment = Comment.objects.create(content=content, article_id=article_id, user_id=user_id)
10 
11     return HttpResponse("ok")
后端视图

 

 

前端模板:

  1 {% extends 'step1/site_base.html' %}
  2 {% block content %}
  3     <div class="article_info">
  4         <h4 class="text-center"><a href="">{{ article_obj.title }}</a></h4>
  5         {{ article_obj.articledetail.content|safe }}
  6     </div>
  7     <div class="clearfix">
  8         <div id="green_channel">
  9             <a href="javascript:void(0);" id="green_channel_digg"
 10                onclick="DiggIt(8343243,cb_blogId,1);green_channel_success(this,'谢谢推荐!');">好文要顶</a>
 11             <a id="green_channel_follow" onclick="follow('ae376d01-5dac-e511-9fc1-ac853d9f53cc');"
 12                href="javascript:void(0);">关注我</a>
 13             <a id="green_channel_favorite" onclick="AddToWz(cb_entryId);return false;"
 14                href="javascript:void(0);">收藏该文</a>
 15             <a id="green_channel_weibo" href="javascript:void(0);" title="分享至新浪微博" onclick="ShareToTsina()"><img
 16                     src="/static/img/icon_weibo_24.png" alt=""></a>
 17             <a id="green_channel_wechat" href="javascript:void(0);" title="分享至微信" onclick="shareOnWechat()"><img
 18                     src="/static/img/wechat.png" alt=""></a>
 19         </div>
 20 
 21         <div id="div_digg">
 22             <div class="diggit digg">
 23                 <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
 24             </div>
 25             <div class="buryit digg">
 26                 <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
 27             </div>
 28             <div class="clear"></div>
 29             <div class="diggword" id="digg_tips"></div>
 30         </div>
 31     </div>
 32 
 33     <div class="comment_show">
 34         <p>评论楼: </p>
 35         <ul class="comment_list list-group">
 36 {#        这里的comment_list没错,是要从后端把数据取出来然后放到这里来进行渲染,但是我们的这个前端模板是article_detail,#}
 37             {#它有自己专属的视图函数来渲染它,所以我们要取数据渲染它就需要去它的函数里面渲染,也就是article_detail函数里面#}
 38             {% for comment in comment_list %}
 39                 <li class="comment_item list-group-item">
 40                     <div class="row">
 41                         <div class="col-md-offset-1">
 42                             <a href="">#{{ forloop.counter }}楼</a>&nbsp;&nbsp;
 43                             <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;
 44                             <span>{{ comment.user.username }}</span>
 45                             <div class="pull-right">
 46                                 <a class="reply_btn" href="#" comment_id="{{ comment.pk }}"
 47                                                        comment_user="{{ comment.user.username }}">回复</a>
 48                             </div>
 49                         </div>
 50                     </div>
 51 
 52                     <div class="row">
 53                         <div class="col-md-offset-1">
 54                             <p>{{ comment.content }}</p>
 55                         </div>
 56                     </div>
 57                 </li>
 58             {% endfor %}
 59 
 60         </ul>
 61     </div>
 62 
 63     <div class="comment">
 64         <p>
 65             <label for="tbCommentAuthor">昵称: </label>
 66             <input type="text" id="tbCommentAuthor" class="author" disabled size="50"
 67                    value="{{ request.user.username }}">
 68         </p>
 69 
 70         <div>
 71             <p><label for="">评论内容:</label></p>
 72             <p><textarea type="text" id="comment_area" cols="60" rows="5"></textarea></p>
 73             <input type="button" id="comment_submit_btn" class="btn btn-primary" value="提交">
 74             <input type="button" id="comment_cancel" class="btn btn-primary" value="取消">
 75         </div>
 76     </div>
 77     {% csrf_token %}
 78 
 79     <script>
 80         {#    $(".digg").click(function(){#}
 81         {#        alert('hello')#}
 82         {#    });#}
 83         //点赞按钮
 84         $(".digg").click(function () {
 85             if ("{{ request.user.username }}") {
 86                 var is_up = $(this).hasClass("diggit");//我们在这里定义了如果div里面有这个class属性的话它就是true否则就是false,因为我们的is_up是bool类型
 87                 {#                console.log(is_up);#}
 88                 $.ajax({
 89                     url: "/step/dig/",
 90                     type: "post",
 91                     data: {
 92                         article_id:{{ article_obj.pk }},
 93                         csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
 94                         is_up: is_up
 95                     },
 96                     success: function (data) {
 97                         var error_info; //声明一个变量共后续使用
 98                         if (data.state) {  //如果点赞操作成功的话就走这一步
 99                             if (is_up) {
100                                 var vae=parseInt($("#digg_count").text())+1;
101                                 $("#digg_count").text(vae);
102                             }
103                             else {
104                                 var val=parseInt($("#bury_count").text())+1;
105                                 $("#bury_count").text(val);
106                             }
107                         }
108                         else {  //如果点赞操作失败的话就走这一步
109                             if (data.first_updown) {
110                                 error_info="已经点赞过了"
111                             } else {
112                                 error_info="已经踩灭过了"
113                             }
114 
115                             $("#digg_tips").html(error_info).css("color", "red");
116 
117 {#                            setTimeout(function () {#}
118 {#                                $("#digg_tips").html("")#}
119 {#                            }, 5000)#}
120                         }
121                     }
122                 })
123             }
124             else {
125                 alert(123)
126             }
127         });
128 
129 
130         //基于ajax绑定提交评论事件
131         var parent_comment_pk = "";
132         $("#comment_submit_btn").click(function () {
133             //区分跟评论和子评论基于一个变量parent_comment_pk,我们的评论是分为根评论和子评论的,要区分对待才能顺利提交,
134             // 因为二者是共享的一个事件为了节省代码,所以就在这里把他们区分开进行处理
135             var content = $("#comment_area").val();  //我们在前端模板语言里面只有三个标签是可以调用val()方法的,
136             // 第一个就是input,第二个就是select,第三个是textarea 请务必牢记
137             if (parent_comment_pk) {  //子评论如果if判断结果为true就是子评论,否则为根评论
138                 var index = content.indexOf("\n");
139                 content = content.slice(index + 1);
140             } else {  //根评论
141                 var content = $("#comment_area").val();
142             }
143 
144             $.ajax({  //我们的ajax是在click里面的,我们要点击然后才能把数据提交到后端进行处理
145                 url: "/step/comment/",
146                 type: "post",
147                 data: {
148                     content: content,
149                     article_id: "{{ article_obj.pk }}",
150                     csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
151                     pd: parent_comment_pk
152                 },
153                 success: function (data) {
154                     console.log(data);
155                 }
156             })
157         });
158 
159 
160         //绑定回复按钮事件  这样写出来是可以在数据库看到他,但是我们在浏览器级别是看不到它的,需要让它在浏览器级别就显示出来该回复是回复的谁,一目了然
161         $(".comment_item .reply_btn").click(function(){
162             //获取焦点
163             $("#comment_area").focus();
164             //设置:@用户名
165             var vae="@"+$(this).attr("comment_user")+"\n";
166             $("#comment_area").val(vae);
167             //获取回复评论的主键值 parent_comment_pk
168             parent_comment_pk=$(this).attr("comment_id")
169         });
170 
171         //取消评论内容
172         $("#comment_cancel").click(function(){
173             $("textarea").val("");
174         });
175 
176     </script>
177 
178 {% endblock %}
HTML(在article_detail上添加功能)

 

在前端模板里面单独摘出来的js代码:

   //基于ajax绑定提交评论事件
        var parent_comment_pk = "";
        $("#comment_submit_btn").click(function () {
            //区分跟评论和子评论基于一个变量parent_comment_pk,我们的评论是分为根评论和子评论的,要区分对待才能顺利提交,
            // 因为二者是共享的一个事件为了节省代码,所以就在这里把他们区分开进行处理
            var content = $("#comment_area").val();  //我们在前端模板语言里面只有三个标签是可以调用val()方法的,
            // 第一个就是input,第二个就是select,第三个是textarea 请务必牢记
            if (parent_comment_pk) {  //子评论如果if判断结果为true就是子评论,否则为根评论
                var index = content.indexOf("\n");
                content = content.slice(index + 1);
            } else {  //根评论
                var content = $("#comment_area").val();
            }

            $.ajax({  //我们的ajax是在click里面的,我们要点击然后才能把数据提交到后端进行处理
                url: "/step/comment/",
                type: "post",
                data: {
                    content: content,
                    article_id: "{{ article_obj.pk }}",
                    csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
                    pd: parent_comment_pk
                },
                success: function (data) {
                    console.log(data);
                }
            })
        });


        //绑定回复按钮事件  这样写出来是可以在数据库看到他,但是我们在浏览器级别是看不到它的,需要让它在浏览器级别就显示出来该回复是回复的谁,一目了然
        $(".comment_item .reply_btn").click(function(){
            //获取焦点
            $("#comment_area").focus();
            //设置:@用户名
            var vae="@"+$(this).attr("comment_user")+"\n";
            $("#comment_area").val(vae);
            //获取回复评论的主键值 parent_comment_pk
            parent_comment_pk=$(this).attr("comment_id")
        });

        //取消评论内容
        $("#comment_cancel").click(function(){
            $("textarea").val("");
        });
js代码

 

相应的配置的静态文件:

 1 input.author{
 2     background-position:3px -3px;
 3 }
 4 
 5 input.author{
 6     background-image:url("/static/img/icon_form.gif");
 7     background-repeat:no-repeat;
 8     border:1px solid #ccc;
 9     padding:4px 4px 4px 30px;
10     width:300px;
11     font-size:13px;
12 }
13 
14 .reply_btn{
15     margin-right:10px;
16 }
static/article_detail.css

 

 

 

=======================================================================================================================================

我们的评论功能一般都是使用评论楼,包括我们所熟知的各大论坛以及各种社交网站,因为评论楼更加便于管理,实现起来也简单得多。但是我们还是需要多学习一下其他的方式

比如我们的评论树功能,【评论树和评论楼最根本的区别就是评论楼可以限制楼层,我最多可以显示多少层,让回复的层级显示出来,再多的楼层,我就不以楼层的形式显示出来了,也就是说对于评论的评论我们的显示不是无限制的,比如微博的骂架,我们如果使用评论楼的话就没有办法把完整的骂战呈现出来,会有断片,所以这个时候评论树就凸现出来了,微博它本身就是依赖于用于的粘性而发展至今的,所以他的评论是核心功能。这个是根据产品而定的,很多时候并不需要那么多的评论树去展开,一般的评论楼层已经足够了】

 

评论树就是我们把数据罗列出来,然后根据该评论的父id去进行筛选,只要此评论的父id跟彼评论的id一致那么此评论就放到彼评论的子评论列表里面,所以我们需要在后端先把这样的数据结构生成,要把子评论列表建立起来,

 我们的评论树的数据构建:

 1 评论树的展开逻辑流程,我们通过
 2 comment_list=[
 3     {"id":1,"content":"111","Pid":None},{"id":2,"content":"222","Pid":None},{"id":3,"content":"333","Pid":None},
 4     {"id":4,"content":"444","Pid":1},{"id":5,"content":"555","Pid":1},{"id":6,"content":"666","Pid":4},
 5     {"id":7,"content":"777","Pid":3},{"id":8,"content":"888","Pid":7},{"id":9,"content":"999","Pid":None},
 6 ]
 7 
 8 for obj in comment_list:
 9     obj["children_list"]=[]
10 
11 ret = []
12 for obj in comment_list:
13     pid = obj['Pid']
14     if pid:
15         for i in comment_list:
16             if i['id'] == pid:  # 这里是判断该字典是否有父评论
17                 i['children_list'].append(obj)
18     else:
19         ret.append(obj)
20 print(ret)
评论树构建的核心基础

 

先来路由系统:

url(r'^show_tree/$'),views.show_tree),

 

后端数据处理views视图:

 1 # 文章详细页
 2 def article_detail(request, username, article_id):
 3     article_obj = Article.objects.filter(pk=article_id).first()
 4     comment_list = Comment.objects.filter(article_id=article_id)
 5     # count = article_obj.comment_count + 1  # 这里本来是要把评论数传到前端使用的,但是我们在前端的ajax里面已经实现了就不用麻烦后端去处理了
 6     comment_li = Comment.objects.filter(article_id=article_id).\
 7         values("nid", "content", 'create_time', 'parent_comment_id', 'user__username')
 8     for obj in comment_li:
 9         obj["children_list"] = []
10 
11     ret = []
12     for obj in comment_li:
13         pid = obj['parent_comment_id']
14         if pid:
15             for i in comment_li:
16                 if i['nid'] == pid:  # 这里是判断该字典是否有父评论
17                     i['children_list'].append(obj)
18         else:
19             ret.append(obj)
20     # print(ret)  # 这里我们已经把它获取到了预期的结构,然后就是把它渲染到页面上了,该怎么做?已经解决了,在前端的js里面实现的
21     return render(request, 'step1/article_detail.html',
22                   {'username': username, 'article_obj': article_obj,
23                    'comment_list': comment_list}, )
Views article_detail

 

1 def get_tree(request, article_id):
2     comment_list = list(Comment.objects.filter(article_id=article_id).values("nid", "content", 'create_time', "parent_comment_id", "user__username").all())
3     for i in comment_list:
4         i['create_time'] = i['create_time'].strftime('%Y-%m-%d %H:%M:%S')
5     # print(comment_list)
6     from django.http import JsonResponse
7     return JsonResponse(comment_list, safe=False)
Views视图get_tree

 

 

如下就是我们的前端HTML模板:

  1 {% extends 'step1/site_base.html' %}
  2 {% block content %}
  3     <div class="article_info">
  4         <h4 class="text-center"><a href="">{{ article_obj.title }}</a></h4>
  5         {{ article_obj.articledetail.content|safe }}
  6     </div>
  7     <div class="clearfix">
  8         <div id="green_channel">
  9             <a href="javascript:void(0);" id="green_channel_digg"
 10                onclick="DiggIt(8343243,cb_blogId,1);green_channel_success(this,'谢谢推荐!');">好文要顶</a>
 11             <a id="green_channel_follow" onclick="follow('ae376d01-5dac-e511-9fc1-ac853d9f53cc');"
 12                href="javascript:void(0);">关注我</a>
 13             <a id="green_channel_favorite" onclick="AddToWz(cb_entryId);return false;"
 14                href="javascript:void(0);">收藏该文</a>
 15             <a id="green_channel_weibo" href="javascript:void(0);" title="分享至新浪微博" onclick="ShareToTsina()"><img
 16                     src="/static/img/icon_weibo_24.png" alt=""></a>
 17             <a id="green_channel_wechat" href="javascript:void(0);" title="分享至微信" onclick="shareOnWechat()"><img
 18                     src="/static/img/wechat.png" alt=""></a>
 19         </div>
 20 
 21         <div id="div_digg">
 22             <div class="diggit digg">
 23                 <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
 24             </div>
 25             <div class="buryit digg">
 26                 <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
 27             </div>
 28             <div class="clear"></div>
 29             <div class="diggword" id="digg_tips"></div>
 30         </div>
 31     </div>
 32 
 33     {#评论树#}
 34     <p class="tree_click">评论树: </p>
 35 
 36     <div class="comment_tree">
 37     </div>
 38 
 39 
 40     {#评论楼#}
 41     <div class="comment_show">
 42         <p>评论楼: </p>
 43         <ul class="comment_list list-group">
 44             {#        这里的comment_list没错,是要从后端把数据取出来然后放到这里来进行渲染,但是我们的这个前端模板是article_detail,#}
 45             {#它有自己专属的视图函数来渲染它,所以我们要取数据渲染它就需要去它的函数里面渲染,也就是article_detail函数里面#}
 46             {% for comment in comment_list %}
 47                 <li class="comment_item list-group-item">
 48                     <div class="row">
 49                         <div class="col-md-offset-1">
 50                             <a href="">#{{ forloop.counter }}楼</a>&nbsp;&nbsp;
 51                             <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;
 52                             <span>{{ comment.user.username }}</span>
 53                             <div class="pull-right">
 54                                 <a class="reply_btn" href="#" comment_id="{{ comment.pk }}"
 55                                    comment_user="{{ comment.user.username }}">回复</a>
 56                             </div>
 57                         </div>
 58                     </div>
 59 
 60                     {% if comment.parent_comment_id %}
 61                         <div class="row">
 62                             <div class="col-md-offset-2 well">
 63                                 <a href="">@ {{ comment.parent_comment.user.username }}</a>
 64                                 <span>{{ comment.parent_comment.content }}</span>
 65                                 <div class="pull-right">
 66                                     <a href="#" class="reply_btn" comment_id="{{ comment.pk }}"
 67                                        comment_user="{{ comment.user.username }}">回复</a>
 68                                 </div>
 69                             </div>
 70                         </div>
 71                     {% endif %}
 72 
 73                     <div class="row">
 74                         <div class="col-md-offset-1">
 75                             <p>{{ comment.content }}</p>
 76                         </div>
 77                     </div>
 78                 </li>
 79             {% endfor %}
 80 
 81         </ul>
 82     </div>
 83 
 84     <div class="comment">
 85         <p>
 86             <label for="tbCommentAuthor">昵称: </label>
 87             <input type="text" id="tbCommentAuthor" class="author" disabled size="50"
 88                    value="{{ request.user.username }}">
 89         </p>
 90 
 91         <div>
 92             <p><label for="">评论内容:</label></p>
 93             <p><textarea type="text" id="comment_area" cols="60" rows="5"></textarea></p>
 94             <input type="button" id="comment_submit_btn" class="btn btn-primary" value="提交">
 95             <input type="button" id="comment_cancel" class="btn btn-primary" value="取消">
 96         </div>
 97     </div>
 98     {#    这里的这个标签不为渲染任何效果,纯粹是为了给我们的js代码需要用到的标签存储变量数据的,仅此而已,所以我们一般都会写到我们的HTML模板的最下方,#}
 99     {#    后期如果有更多的数据都可以写到这里来,目前仅仅这一个变量所以就写它一个,#}
100     <div class="info" username="{{ request.user.username }}" article_pk="{{ article_obj.pk }}"></div>
101     {% csrf_token %}
102 
103     <script>
104         {#    $(".digg").click(function(){#}
105         {#        alert('hello')#}
106         {#    });#}
107         //点赞按钮
108         $(".digg").click(function () {
109             if ("{{ request.user.username }}") {
110                 var is_up = $(this).hasClass("diggit");//我们在这里定义了如果div里面有这个class属性的话它就是true否则就是false,因为我们的is_up是bool类型
111                 {#                console.log(is_up);#}
112                 $.ajax({
113                     url: "/step/dig/",
114                     type: "post",
115                     data: {
116                         article_id:{{ article_obj.pk }},
117                         csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
118                         is_up: is_up
119                     },
120                     success: function (data) {
121                         var error_info; //声明一个变量共后续使用
122                         if (data.state) {  //如果点赞操作成功的话就走这一步
123                             if (is_up) {
124                                 var vae = parseInt($("#digg_count").text()) + 1;
125                                 $("#digg_count").text(vae);
126                             }
127                             else {
128                                 var val = parseInt($("#bury_count").text()) + 1;
129                                 $("#bury_count").text(val);
130                             }
131                         }
132                         else {  //如果点赞操作失败的话就走这一步
133                             if (data.first_updown) {
134                                 error_info = "已经点赞过了"
135                             } else {
136                                 error_info = "已经踩灭过了"
137                             }
138 
139                             $("#digg_tips").html(error_info).css("color", "red");
140 
141                             setTimeout(function () {
142                                 $("#digg_tips").html("")
143                             }, 5000)
144                         }
145                     }
146                 })
147             }
148             else {
149                 alert(123)
150             }
151         });
152 
153 
154         //基于ajax绑定提交评论事件{评论楼显示效果}
155         var parent_comment_pk = "";
156         $("#comment_submit_btn").click(function () {
157             //区分跟评论和子评论基于一个变量parent_comment_pk,我们的评论是分为根评论和子评论的,要区分对待才能顺利提交,
158             // 因为二者是共享的一个事件为了节省代码,所以就在这里把他们区分开进行处理
159             var content = $("#comment_area").val();  //我们在前端模板语言里面只有三个标签是可以调用val()方法的,
160             // 第一个就是input,第二个就是select,第三个是textarea 请务必牢记
161             if (parent_comment_pk) {  //子评论如果if判断结果为true就是子评论,否则为根评论
162                 var index = content.indexOf("\n");
163                 content = content.slice(index + 1);
164             } else {  //根评论
165                 var content = $("#comment_area").val();
166             }
167 
168             //清空输入框的内容
169             $("textarea").val("");
170             {#            alert(content);#}
171 
172             $.ajax({  //我们的ajax是在click里面的,我们要点击然后才能把数据提交到后端进行处理
173                 url: "/step/comment/",
174                 type: "post",
175                 data: {
176                     content: content,
177                     article_id: "{{ article_obj.pk }}",
178                     csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
179                     pd: parent_comment_pk
180                 },
181                 success: function (data) {
182                     //我们需要在这里把变量的名字都替换掉,然后再浏览器渲染出来效果,如何替换
183                     // 这里是ajax内容实现后的返回结果,我们要在这里处理页面渲染问题,我们的变量就只有article_obj是article表格里面的一个object对象,然后就是我们的comment_list是一个集合,里面装的是所有的comment,我们需要一个抓手去通过它找到我们的comment表格里面的对应的字段和值,只要找到了这个东西就可以轻易取出我们需要的数据,content和create_time都轻易能获取到,但是这个抓手从哪儿来
184                     var data = JSON.parse(data);
185                     var floor_count = $(".list-group .list-group-item").length;
186                     var create_time = data.create_time;
187                     var content = data.cont;
188                     var user = $(".info").attr("username");//我们这样写比直接后端传过来的request.user.username效果要好,
189                     // 我们的js代码按照规范来都是需要写到静态文件里面的,如果我们在下面的字符串里面直接写
190                     // request.user.username的话(以下简称为it),作为静态文件的js代码就仅仅是把it作为一个字符串进行渲染,
191                     // 也就是说它不会有逻辑代码在里面转换成你需要的username,所以我们如果是使用这种方式去写的话,即便作为静态文件,
192                     // 我们在渲染的时候也可以从我们的HTML模板里面拿到值,因为我们的静态文件加载的时候就是为了渲染我们的这个HTML模板的,
193                     // 而我们的HTML模板里面的逻辑代码则是跟我们的views视图函数紧密相连的,所以,是万无一失的,
194                     // 我们以后有很多其他的变量需要在后期用到的话都是可以存入到我们的HTML标签里面的
195                     s = '<li class="comment_item list-group-item"><div class="row"><div class="col-md-offset-3"><a href="">#' + floor_count + '楼</a>&nbsp;&nbsp;<span>' + create_time + '</span>&nbsp;&nbsp;<span>' + user + '</span><p><span>' + content + '</span></p></div></div></li>';
196                     $(".comment_list").append(s);
197 
198                 }
199             })
200         });
201 
202 
203         //绑定回复按钮事件
204         $(".comment_item .reply_btn").click(function () {
205             //获取焦点
206             $("#comment_area").focus();
207             //设置:@用户名
208             var vae = "@" + $(this).attr("comment_user") + "\n";
209             $("#comment_area").val(vae);
210             //获取回复评论的主键值 parent_comment_pk
211             parent_comment_pk = $(this).attr("comment_id")
212         });
213 
214         //取消评论内容
215         $("#comment_cancel").click(function () {
216             $("textarea").val("");
217         });
218 
219 
220         //这里把评论树展示出来
221         $(".tree_click").click(function () {
222                 $.ajax({
223                     url: "/step/show_tree/" +{{ article_obj.pk }},
224                     success: function (data) {
225                         console.log(data);
226                         var comment_li = data;
227                         var comment_html = "";
228                         $.each(comment_li, function (index, comment) {
229                             var nid = comment.nid;
230                             var content = comment.content;
231                             var pid = comment.parent_comment_id;
232                             var username = comment.user__username;
233                             var create_time = comment.create_time;
234                             comment_html = ' <div class="comment_item" style="margin-left:20px;">' +
235                                 '<span>' + username + '</span>&nbsp;&nbsp;' +
236                                 '<span>' + create_time + '</span>&nbsp;&nbsp;' +
237                                 '<span class="content"  tree_id=' + nid + '>' + content + '</span>' +
238                                 '</div>';
239 
240                             comment_text = ' <li class="comment_item list-group-item">' +
241                                 '<div class="row" ><div class="col-md-offset-1">' +
242                                 '<span>' + create_time + '</span>&nbsp;&nbsp;<span>' + username + '</span> ' +
243                                 '<div class="pull-right"> ' +
244                                 '<a class="reply_btn" href="#" comment_id=' + nid + ' ' +
245                                 'comment_user=' + username + '>回复</a> </div> </div> <div class="row"> ' +
246                                 '<div class="col-md-offset-1"> <p parent_id=' + nid + '>' + content + '</p> </div> </div> </li>';
247 
248                             content_file = ' <div class="row"><div class="col-md-offset-2 well" style="margin-right:30px;">' +
249                                 '<a href="">@ ' + username + '</a> ' +
250                                 '<span parent_id=' + nid + '>' + content + '</span> <div class="pull-right"> ' +
251                                 '<a href="#" class="reply_btn" comment_id=' + nid + ' ' +
252                                 'comment_user=' + username + '>回复</a> </div> </div></div>';
253 
254                             if (pid) {
255                                 $("[parent_id=" + pid + "]").parent().prepend(content_file);
256                             } else {
257                                 $(".comment_tree").append(comment_text);
258                             }
259                             {#                                    if(pid){ //有子评论#}
260                             {#                                        $("[tree_id="+pid+"]").parent().append(comment_html);#}
261 
262                             //这里的$('[class="content"]')语法就是找到含有该键值对属性的标签,
263                             // 只要是符合条件都可以使用这样的方法去查找,包括我们常用的class属性和id属性都是可以的,
264                             // 因为我们的class和id使用频率较高,所以我们一般用更加高效的.或者#去查找,
265                             // 其他的情况下我们没有那么高效的api方法就使用这样的方法去查找
266                             {#                                    }else{ //没有子评论#}
267                             {#                                        $(".comment_tree").append(comment_html);#}
268                             {#                                    }#}
269                         })
270 
271                     }
272 
273 
274                 })
275         })
276 
277 
278     </script>
279 
280 {% endblock %}
article_detail的HTML

 

我们把js代码单独拎出来:

 1    //这里把评论树展示出来
 2         $(".tree_click").click(function () {
 3                 $.ajax({
 4                     url: "/step/show_tree/" +{{ article_obj.pk }},
 5                     success: function (data) {
 6                         console.log(data);
 7                         var comment_li = data;
 8                         var comment_html = "";
 9                         $.each(comment_li, function (index, comment) {
10                             var nid = comment.nid;
11                             var content = comment.content;
12                             var pid = comment.parent_comment_id;
13                             var username = comment.user__username;
14                             var create_time = comment.create_time;
15                            
16 #这里是没有样式的素版
17  comment_html = ' <div class="comment_item" style="margin-left:20px;">' +
18                                 '<span>' + username + '</span>&nbsp;&nbsp;' +
19                                 '<span>' + create_time + '</span>&nbsp;&nbsp;' +
20                                 '<span class="content"  tree_id=' + nid + '>' + content + '</span>' +
21                                 '</div>';
22 
23 # 这里是bootstrap版本的
24                             comment_text = ' <li class="comment_item list-group-item">' +
25                                 '<div class="row" ><div class="col-md-offset-1">' +
26                                 '<span>' + create_time + '</span>&nbsp;&nbsp;<span>' + username + '</span> ' +
27                                 '<div class="pull-right"> ' +
28                                 '<a class="reply_btn" href="#" comment_id=' + nid + ' ' +
29                                 'comment_user=' + username + '>回复</a> </div> </div> <div class="row"> ' +
30                                 '<div class="col-md-offset-1"> <p parent_id=' + nid + '>' + content + '</p> </div> </div> </li>';
31 
32                             content_file = ' <div class="row"><div class="col-md-offset-2 well" style="margin-right:30px;">' +
33                                 '<a href="">@ ' + username + '</a> ' +
34                                 '<span parent_id=' + nid + '>' + content + '</span> <div class="pull-right"> ' +
35                                 '<a href="#" class="reply_btn" comment_id=' + nid + ' ' +
36                                 'comment_user=' + username + '>回复</a> </div> </div></div>';
37 
38                             if (pid) {
39                                 $("[parent_id=" + pid + "]").parent().prepend(content_file);
40                             } else {
41                                 $(".comment_tree").append(comment_text);
42                             }
43                             {#                                    if(pid){ //有子评论#}
44                             {#                                        $("[tree_id="+pid+"]").parent().append(comment_html);#}
45 
46                             //这里的$('[class="content"]')语法就是找到含有该键值对属性的标签,
47                             // 只要是符合条件都可以使用这样的方法去查找,包括我们常用的class属性和id属性都是可以的,
48                             // 因为我们的class和id使用频率较高,所以我们一般用更加高效的.或者#去查找,
49                             // 其他的情况下我们没有那么高效的api方法就使用这样的方法去查找
50                             {#                                    }else{ //没有子评论#}
51                             {#                                        $(".comment_tree").append(comment_html);#}
52                             {#                                    }#}
53                         })
54 
55                     }
56 
57 
58                 })
59         })
javascript

 

有一个小bug还是没有解决掉,就是我们的评论树在使用ajax展开的时候,我们绑定的是点击事件,我们只能点击一次就可以看到预期的效果,但是如果我们点击超过一次的话,就会重复显示内容,这一点还是很可怕的,我们的用户不可能就只是点击一次,这里需要怎么解决?

 

posted @ 2018-02-27 08:40  dream-子皿  阅读(127)  评论(0)    收藏  举报