zoukankan      html  css  js  c++  java
  • 使用thymeleaf模板实现博客评论的异步刷新

    使用thymeleaf模板实现博客评论的异步刷新

    最简单的一个要求:用户可以在博客下面进行评论,然后评论后点击提交后直接上传到数据库,并且局部刷新
    这是前端页面的展示,使用的semanticUI进行构造出来的模型,另外semanticUi已经不再更新了。
    进入重点:如果想要进行局部刷新,使用fragment标签进行更新,如下第二行可以看到将这一块的所有信息都给包裹起来。

    		<div id="comment-container" class="ui teal segment">
                <div th:fragment="commentList">
                    <div class="ui threaded comments" style="max- 100%">
                        <h3 class="ui dividing header">评论</h3>
                        <div class="comment"  th:each="comment : ${comments}">
                            <a class="avatar">
                                <img src="https://unsplash.it/100/100?image=1005" th:src="@{${comment.avatar}}">
                            </a>
                            <div class="content" >
                                <a class="author" >
                                    <span th:text="${comment.nickname}">Matt</span>
                                    <div class="ui mini basic teal left pointing label m-padded-mini" th:if="${comment.adminComment}">
                                        博主
                                    </div>
                                </a>
                                <div class="metadata">
                                    <span class="date" th:text="${#dates.format(comment.createTime,'yyyy-MM-dd HH:mm')}">Today at 5:42PM</span>
                                </div>
                                <div class="text" th:text="${comment.content}">
                                    How artistic!
                                </div>
                                <div class="actions">
                                    <a class="reply" data-commentid="1" data-commentnickname="Matt" th:attr="data-commentid=${comment.id},data-commentnickname=${comment.nickname}" onclick="reply(this)">回复</a>
                                </div>
                            </div>
    
                            <!--第二层-->
                            <div class="comments" th:if="${#arrays.length(comment.replyComments)}>0">
                                <div class="comment"  th:each="reply : ${comment.replyComments}">
                                    <a class="avatar">
                                        <img src="https://unsplash.it/100/100?image=1005" th:src="@{${reply.avatar}}">
                                    </a>
                                    <div class="content" >
                                        <a class="author" >
                                            <span th:text="${reply.nickname}">小红</span>&nbsp;
                                            <div class="ui mini basic teal left pointing label m-padded-mini" th:if="${reply.adminComment}">
                                                博主
                                            </div>
                                            <span th:text="|@ ${reply.parentComment.nickname}|" class="m-teal">@ 小白</span>
                                        </a>
                                        <div class="metadata">
                                            <span class="date" th:text="${#dates.format(reply.createTime,'yyyy-MM-dd HH:mm')}">Today at 5:42PM</span>
                                        </div>
                                        <div class="text" th:text="${reply.content}">
                                            How artistic!
                                        </div>
                                        <div class="actions">
                                            <a class="reply" data-commentid="1" data-commentnickname="Matt" th:attr="data-commentid=${reply.id},data-commentnickname=${reply.nickname}" onclick="reply(this)">回复</a>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
    
            </div>
    

    这里是提交表单的所有内容,由于评论是一个嵌套的类,即一个评论可以有多个评论,一层层的嵌套下来,在这里需要注意的是,使用springdatajpa的过程中,尽量避免使用Lombok插件中的@Data进行注解类,它会直接产生所有属性的toString,如果使用了,会报出stackoverflow异常,原因是你一直调用的toString方法,一直递归下去,导致栈溢出。最简便的方法就是破坏toString方法中的输出该类的信息,在这里就是不要输出Comment的信息。


    提交评论信息的同时,需要设置一个字段证明是新提交的信息而不是回复别人的信息。<input type="hidden" name="parentComent.id" value="-1">这段代码就是实现这个功能,如果是评论博客而不是回复别人的信息,则直接将parentComent.id设置成-1,然后在后端进行判断如果是-1则是新评论。

            <div id="comment-form" class="ui form">
                <input type="hidden" name="blog.id" th:value="${blog.id}">
                <input type="hidden" name="parentComent.id" value="-1">
                <div class="field">
                    <textarea name="content" placeholder="请输入评论信息..."></textarea>
                </div>
                <div class="fields">
                    <div class="field m-mobile-wide m-margin-bottom-small">
                        <div class="ui left icon input">
                            <i class="user icon"></i>
                            <input type="text" name="nickname" placeholder="姓名" th:value="${session.user}!= null ? ${session.user.nickName}">
                        </div>
                    </div>
                    <div class="field m-mobile-wide m-margin-bottom-small">
                        <div class="ui left icon input">
                            <i class="mail icon"></i>
                            <input type="text" name="email" placeholder="邮箱" th:value="${session.user}!= null ? ${session.user.email}">
                        </div>
                    </div>
                    <div class="field  m-margin-bottom-small m-mobile-wide">
                        <button id="commentpost-btn" type="button" class="ui teal button m-mobile-wide"><i class="edit icon"></i>发布</button>
                    </div>
                </div>
    
            </div>
    

    js部分:

    $(function () {
        //当页面加载完成之后,需要把评论都给加载出来
        $("#comment-container").load(/*[[@{/comments/{id}(id=${blog.id})}]]*/"comments/6");
    });
    
    $("#commentpost-btn").click(function () {
        let boo=$('.ui.form').form('validate form');
        if (boo){
            postData();
            console.log('校验成功');
        }else{
            console.log('校验失败');
        }
    });
    function postData(){
        $("#comment-container").load(/*[[@{/comments}]]*/"",{
            "parentComment.id":$("[name='parentComent.id']").val(),
            "blog.id":$("[name='blog.id']").val(),
            "nickname":$("[name='nickname']").val(),
            "email":$("[name='email']").val(),
            "content":$("[name='content']").val()
        },function (responseTxt,statusTxt,xhr) {
            clearContent();
            //滚动到最上面的评论
    
        })
    }
    function clearContent(){
        $("[name='content']").val('');
        $("[name='parentComent.id']").val(-1);
        $("[name='content']").attr("placeholder","请输入评论信息...");
    }
    
    function reply(obj) {
        let commentId=$(obj).data('commentid');
        let nickNickname=$(obj).data('commentnickname');
        $("[name='content']").attr("placeholder","@"+nickNickname).focus();
        $("[name='parentComent.id']").val(commentId);
        $(window).scrollTo($("#comment-form"),500);
    }
    

    以上着重讲下异步的过程:
    commentpost-btn是提交按钮的id,有一个点击事件,点击后进行提交 postData()方法,然后找到div的id为comment-container的标签进行重新加载,加载的数据源为

    /*[[@{/comments}]]*/
    

    也就是找到controller层的url进行提交数据,然后将表单中的数据进行传递给后台,后台进行处理:

    @PostMapping("/comments")
        public String post(Comment comment, HttpSession session){
            Long blogId = comment.getBlog().getId();
            comment.setBlog(blogService.getBlog(blogId));
            User user=(User)session.getAttribute("user");
            if (user!=null){
                comment.setAvatar(user.getAvatar());
                comment.setAdminComment(true);
               /* comment.setNickname(user.getNickName());*/
            }else{
                comment.setAvatar(avatar);
            }
            commentService.saveComment(comment);
            return "redirect:/comments/" + blogId;
        }
    

    提交后在重定向给获取所有评论的controller的url:

    @GetMapping("/comments/{blogId}")
        public String comments(@PathVariable Long blogId, @NotNull Model model){
            model.addAttribute("comments",commentService.listCommentByBlogId(blogId));
            return "blog :: commentList";
        }
    

    这里将所有的数据全部返回给blog页面的commentList的fragment。
    到此,异步刷新结束。

    $(function () {
        //当页面加载完成之后,需要把评论都给加载出来
        $("#comment-container").load(/*[[@{/comments/{id}(id=${blog.id})}]]*/"comments/6");
    });
    

    这段代码的意思是党页面加载完成之后,将所有的评论都加载出来。

    博客网站 https://yamon.top 个人网站 https://yamon.top/resume GitHub网站 https://github.com/yamonc 欢迎前来访问
  • 相关阅读:
    45 岁,还写代码吗?
    给你 8 个接私活的网站
    一文回顾 Java 入门知识(下)
    5 种前途迷茫的编程语言
    JVM 内存的结构模型、堆与堆栈原理、对象在内存中的结构
    mysql 索引是否能提高UPDATE,DELETE,INSERT 处理速度
    【诈尸】【游戏】多人联机游戏推荐
    250.统计同值子树
    366. 寻找二叉树的叶子节点
    156.上下翻转二叉树
  • 原文地址:https://www.cnblogs.com/chenyameng/p/12250700.html
Copyright © 2011-2022 走看看