种类细节页面 - 学习 Web 开发 编辑
种类细节页面,需要利用_id
字段值 (自动生成) ,以呈现特定种类实例的信息。此页面应该呈现种类名称,各个种类的所有书本列表(每本书都连结到书本的细节页面)。
控制器
打开 /controllers/genreController.js ,并在档案最上方引用 async 和 Book 模组。
var Book = require('../models/book');
var async = require('async');
找到导出的genre_detail
()
控制器方法,并将其替换为以下代码。
// Display detail page for a specific Genre.
exports.genre_detail = function(req, res, next) {
async.parallel({
genre: function(callback) {
Genre.findById(req.params.id)
.exec(callback);
},
genre_books: function(callback) {
Book.find({ 'genre': req.params.id })
.exec(callback);
},
}, function(err, results) {
if (err) { return next(err); }
if (results.genre==null) { // No results.
var err = new Error('Genre not found');
err.status = 404;
return next(err);
}
// Successful, so render
res.render('genre_detail', { title: 'Genre Detail', genre: results.genre, genre_books: results.genre_books } );
});
};
该方法使用async.parallel()
,并行查询类型名称及其相关联的书本,并在(如果)两个请求成功完成时,回调呈现页面。
所需种类记录的 ID ,在 URL 的末尾编码,并根据路由定义(/genre/:id)自动提取。通过请求参数(req.params.id
)
在控制器内访问 ID。它在Genre.findById()
中用于获取当前种类。它还用于获取符合当前种类的所有Book
对象,就是在种类字段中具有种类ID的那些 Book.find({ 'genre': req.params.id })
。
注意: 如果数据库中不存在该类型(即它可能已被删除),则findById()
将成功返回,但没有结果。在这种情况下,我们想要显示一个“未找到”页面,因此我们创建一个Error
对象,并将其传递给链中的下一个中间件函数next
。
if (results.genre==null) { // No results.
var err = new Error('Genre not found');
err.status = 404;
return next(err);
}
然后,此消息将传播给我们的错误处理代码(这是在我们生成应用程序框架时设置的 - 有关更多信息,请参阅处理错误)。
渲染的视图是 genre_detail,它传递了该类型的标题title
,种类genre
和书本列表的变量(genre_books
)。
视图
创建 /views/genre_detail.pug ,并填写底下文字:
extends layout
block content
h1 Genre: #{genre.name}
div(style='margin-left:20px;margin-top:20px')
h4 Books
dl
each book in genre_books
dt
a(href=book.url) #{book.title}
dd #{book.summary}
else
p This genre has no books
这个视图跟我们其它的模板非常相似。主要的差别在于,我们不使用 title
传送第一个标题 (虽然它还是用在底层的 layout.pug 模板,设定页面的标题)。
它看起來像是?
运行本应用,并打开浏览器访问 http://localhost:3000/。选择 All genres 连结,然后选择其中一个种类 (例如,"Fantasy")。如果每样东西都设定正确了,你的页面看起来应该像底下的截图。
您可能会收到与此类似的错误:
Cast to ObjectId failed for value " 59347139895ea23f9430ecbb" at path "_id" for model "Genre"
这是来自 req.params.id 的 mongoose 错误。要解决这个问题,首先需要在 genreController.js 页面上要求mongoose,如下所示:
var mongoose = require('mongoose');
然后使用 mongoose.Types.ObjectId()将 id 转换为可以使用的。例如:exports.genre_detail = function(req, res, next) {
var id = mongoose.Types.ObjectId(req.params.id);
...
下一步
- 回到 Express 教程 5: 呈现图书馆数据
- 继续教程 5 下一个部分: 书本细节页面
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论