今天我们来实现博客的查看, 修改, 删除功能.
上一次我们已经实现了写博客, 发布博客, 然后回到首页显示所有博客. 但是呢, 我们还不能点进去查看博客的具体内容, 也不能对博客进行什么操作.今天我们就来搞定这个.
分析
首先以查看博客为例分析一下实现的思路, 很明显逻辑应该是:
- 在首页上每个显示的文章都添加一个链接, 这个链接就是一个路由, 而且还能够唯一确定一篇文章, 所以链接还要传递几个参数.
- 在views文件夹新建模板文件, 显示博客内容.
- 然后, 在index.js添加路由规则, 在routes文件夹新建相应路由文件. 用post模型提供的方法, 对数据库操作, 进行逻辑处理.然后返回数据渲染模板.
同理, 删除操作和修改也是一个道理.
开始干活
打开index.ejs, 给博客标题添加链接. 代码是这样地.
<div class="post-list-wrapper">
<div class="post-list">
<% if(!posts.length) { %>
<p class="hint">
no blog you search yet~
</p>
<% } %>
<% posts.forEach(function(post, index) { %>
<div class="post-item">
<a href="/u/<%= post.author %>/<%= post.title%>/<%= post.time.till_minute%>" class="link post-title"><%= post.title %></a>
<div class="info">
<label for="author">作者</label>
<a class="link info-tag"><%= post.author %></a> |
<label for="time">时间</label>
<span class="time info-tag"><%= post.time.till_minute %></span>
</div>
<p class="content-wrap">
<%= post.content %>
</p>
</div>
<% }) %>
</div>
</div>
可以看到, 我们传递了三个参数, 作者的名字, 标题, 和发布的时间, 这样就可以唯一确定一个博客了. 然后在views文件夹新建模板文件
<article class="article-wrapper">
<div class="post-item">
<div class="options">
<a href="/u/<%= post.author %>/<%= post.title%>/<%= post.time.till_minute%>" class="title link"><%= post.title %></a>
<% if(user) {%>
<% if(post.author == user.name){ %>
<a href="/edit/<%= post.author %>/<%= post.title%>/<%= post.time.till_minute %>" class="edit link">编辑</a>
<a href="/remove/<%= post.author %>/<%= post.title%>/<%= post.time.till_minute %>" class="remove link">删除</a>
<% }%>
<% }%>
</div>
<div class="info">
<label for="author">作者</label>
<a class="author link info-tag" href="/u/<% post.author%>"><%= post.author %></a> |
<label for="time">时间</label>
<span class="time info-tag"><%= post.time.till_minute %></span>
<div class="tags">
<% post.tags.forEach(function(tag, index) {
%>
<span class="tag"><%= tag %></span>
<% }) %>
</div>
</div>
<p class="content-wrap">
<%= post.content %>
</p>
</div>
</article>
我们可以看到我们只对博客发布者显示编辑和删除按钮, 这是合乎逻辑的.另外要注意的是, 模板的数据名称和后端要一致, 这是前后端对接的很重要的一个环节. 如果你出现模板提示错误说某个数据未定义,那么一般就是后端返回数据和前端数据不统一导致的.
然后, 我们要在model/post.js添加一个方法getOne来从数据库拿到某某一篇文章.代码如下:
Post.getOne = function(author, title, time, callback) {
db.get().collection('posts', function(err, collection) {
if (err) {
mongodb.close();
return callback(err);
}
var doc = {
"author": author,
"title": title,
"time.till_minute": time,
};
collection.findOne(doc, function(err, post) {
if (err) {
mongodb.close();
return callback(err);
}
return callback(null, post);
});
});
};
然后在routs文件夹新建article.js, 添加以下代码var Post = require(‘../model/post’);
var express = require(‘express’);
var router = express.Router();
router.get('/', function(req, res) {
User.getByName(req.params.name, function(err, user) {
if (!user) {
return res.redirect('/');
}
Post.getOne(req.params.name, req.params.title, req.params.time, function(err, post) {
if (err) {
req.flash('error', err);
}
res.render('article', {
author: user.name,
user: req.session.user,
post: post,
});
});
});
});
如果一切没错的话, 再次运行app, 点击任意一个博客的标题, 应该是这样子的.
结论
通过今天的工作, 我们对前后端对接的流程走了一遍, 重点在于数据接口的统一. 今天的代码在day04
(今天的逼就装到这里,谢谢大家)