前言
本节内容主要是构建一个对博客文章的评论功能,由前端使用 ajax 通过 GET 方式向 /api/comment/post 路由提交评论,服务器再将其保存在数据库中。当用户没有登录时,会提示用户没有登录,不能评论。用户登陆以后,会显示一个评论文本框,用来给用户提交评论,提交后的评论会使用 ajax 进行局部刷新在博客文章的下方显示出来。提交的时候,会在前端进行简单的验证吗,验证通过后才能提交评论,否则 return false。
评论的前端界面
评论的界面,使用模板引擎的条件判断来根据当前用户是否登录来显示不同的界面,也就是使用前面 cookie 的信息来进行判断,若 userInfo.userid 存在则显示评论界面,反之提示未登录。为方便 ajax 获取需要向后端传送的文章 ID ,在这里将文章的 ID 设为一个隐藏的 input 的属性。
在 /views/main/views.ejs 中,在文章内容部分 (<%- contentHtml %>) 后,添加上如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <div class="text-muted text-center">------------本文结束------------</div> <div class="well"> <input type="hidden" id="contentId" value="<%= content.id %>"> <% if (userInfo.userid) {%> <div class="form-group"> <label for="name">说点什么</label> <textarea class="form-control" rows="3" cols="4" placeholder="输入评论" id="comment"></textarea> <br> <button class="form-control btn btn-primary" id="comment-btn">提交</button> </div> <% } else { %> <div class="alert alert-danger">请先登录!</div> <% } %> <div class="commentList"> <div> <span>作者 | 时间</span> <p>评论内容</p> </div> </div> </div>
|
数据库中的评论存储处理
为了方便,我暂时仅将博客的评论新增为文章集合的一个属性,并未新设一个集合。修改 /schemas/contents.js 文件,将博客文章的存储格式新增一个名为 comment 字段,类型为数组,默认为空数组。
1 2 3 4
| comment: { type: Array, default: [] }
|
如此一来,博客文章的评论的数据库储存格式也暂时完成。
后端 api 处理
后端关于评论处理的接口主要有两个,一个是提交评论,另一个是读取评论。提交评论是由前端使用 ajax 通过 POST 的方式向服务器提交评论的用户和评论的内容,再由服务器进行相应的格式化处理后存入数据库中。而获取评论同样也是前端使用户 ajax 通过 GET 的方式向服务器提交需要获取评论的文章 ID ,再有服务器将该文章的所有评论从数据库中读取出来后传送给前端,由 ajax 局部刷新加载出来。
在 /routes/api.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 39 40 41 42 43 44 45 46 47
| router.get("/comment", (req, res) => { let contentId = req.query.contentId || "";
contentModel.findById(contentId, (err, content) => { if (!err) { res.json(content.comment); return; } else { throw err; return; } }); });
router.post("/comment/post", (req, res) => { let contentId = req.body.contentId; let comment = req.body.comment;
let commentData = { username: req.userInfo.username, postTime: new Date(), content: comment }
contentModel.findById(contentId, (err, content) => { if (!err) { content.comment.push(commentData); content.save(); res.json(content); return; } else { throw err; return; } }); });
|
前端 ajax 处理
在 /public/js 文件夹中,新建一个 comment.js 文件用来处理评论相关的 ajax。内容如下:
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
| $(() => { (() => { $subBtn = $("#comment-btn"); $comment = $("#comment"); $subBtn.on("click", () => { if ($comment.val() === "") { alert("评论内容不能为空"); return; } $.ajax({ type: "post", url: "/api/comment/post", data: { contentId: $("#contentId").val(), comment: $comment.val() }, dataType: "json", success: (result) => { renderComment(); $comment.val("") } }); }); })();
renderComment = () => { $.ajax({ type: "get", url: "/api/comment/", data: { contentId: $("#contentId").val(), }, dataType: "json", success: (result) => { let commentList = ""; for (let i = result.length - 1; i >= 0; i--) { let postTime = commentList += ` <div> <span>用户:${ result[i].username } | 时间:${ result[i].postTime }</span> <p>${ result[i].content }</p> </div> ` } $(".commentList").html(commentList); } }); }
renderComment();
});
|
测试
最后再重启服务器,刷新客户端进行测试