图书详情页面
图书详情页 需要显示特定Book(通过其自动生成的_id 字段值识别)的信息,以及图书馆中每本关联副本(BookInstance)的信息。无论何时显示作者、类型或图书实例,都应将其链接到该项的相应详情页。
控制器
打开 /controllers/bookController.js。找到导出的 book_detail() 控制器方法,并将其替换为以下代码。
// Display detail page for a specific book.
exports.book_detail = async (req, res, next) => {
// Get details of books, book instances for specific book
const [book, bookInstances] = await Promise.all([
Book.findById(req.params.id).populate("author").populate("genre").exec(),
BookInstance.find({ book: req.params.id }).exec(),
]);
if (book === null) {
// No results.
const err = new Error("Book not found");
err.status = 404;
return next(err);
}
res.render("book_detail", {
title: book.title,
book,
book_instances: bookInstances,
});
};
注意:此步骤中我们无需引入任何额外的模块,因为在实现主页控制器时已导入了依赖项。
此方法与为图书类型详情页所述的方法完全相同。路由控制器函数使用 Promise.all() 并行查询指定的 Book 及其关联的副本(BookInstance)。如果未找到匹配的图书,则返回一个带有“404: Not Found”错误的 Error 对象。如果找到图书,则使用“book_detail”模板呈现检索到的数据库信息。由于 'title' 键用于为网页命名(如 'layout.pug' 的头部中定义),这次我们在呈现网页时传递了 results.book.title。
视图
创建 /views/book_detail.pug 并添加以下文本。
extends layout
block content
h1 Title: !{book.title}
p #[strong Author: ]
a(href=book.author.url) #{book.author.name}
p #[strong Summary:] !{book.summary}
p #[strong ISBN:] #{book.isbn}
p #[strong Genre: ]
each val, index in book.genre
a(href=val.url) #{val.name}
if index < book.genre.length - 1
|,
div(style='margin-left:20px;margin-top:20px')
h2(style='font-size: 1.5rem;') Copies
each val in book_instances
hr
if val.status=='Available'
p.text-success #{val.status}
else if val.status=='Maintenance'
p.text-danger #{val.status}
else
p.text-warning #{val.status}
p #[strong Imprint:] #{val.imprint}
if val.status!='Available'
p #[strong Due back:] #{val.due_back}
p #[strong Id: ]
a(href=val.url) #{val._id}
else
p There are no copies of this book in the library.
请注意 !{book.title} 和 !{book.summary} 前面的 !,这可确保值不会被转义显示。这样做是因为我们已经以编程方式对要显示的数据进行了清理,再次清理将会显示我们“清理过的标记”,而不是原始文本的安全版本。我们选择不对作者、图书类型等执行相同操作(尽管我们可以这样做),因为我们不期望它们包含需要清理的任何“危险”字符。
此模板中的几乎所有其他内容在前几节中都已演示过。
注意:与图书关联的图书类型列表在模板中实现如下。这会在与图书关联的每种图书类型后添加逗号和不间断空格,但最后一个除外。
p #[strong Genre: ]
each val, index in book.genre
a(href=val.url) #{val.name}
if index < book.genre.length - 1
|,
它看起来怎么样?
运行应用程序,并在浏览器中打开 https://:3000/。选择所有图书链接,然后选择其中一本书。如果一切设置正确,您的页面应类似于以下屏幕截图。

后续步骤
- 返回 Express 教程第 5 部分:显示图书馆数据。
- 请继续学习第 5 部分的下一篇文章:作者详情页。