图书实例详情页面和挑战
图书实例详情页面
BookInstance
详情页面需要显示每个BookInstance
的信息,使用其(自动生成的)_id
字段值进行识别。这将包括Book
名称(作为指向图书详情页面的链接)以及记录中的其他信息。
控制器
打开/controllers/bookinstanceController.js。找到导出的bookinstance_detail()
控制器方法,并将其替换为以下代码。
// Display detail page for a specific BookInstance.
exports.bookinstance_detail = asyncHandler(async (req, res, next) => {
const bookInstance = await BookInstance.findById(req.params.id)
.populate("book")
.exec();
if (bookInstance === null) {
// No results.
const err = new Error("Book copy not found");
err.status = 404;
return next(err);
}
res.render("bookinstance_detail", {
title: "Book:",
bookinstance: bookInstance,
});
});
实现方式与其他模型详情页面的实现方式非常相似。路由控制器函数使用从 URL 中提取的特定图书实例的 ID(使用路由)调用BookInstance.findById()
,并通过请求参数在控制器中访问:req.params.id
。然后它调用populate()
来获取关联Book
的详细信息。如果找不到匹配的BookInstance
,则会将错误发送到 Express 中间件。否则,将使用**bookinstance_detail.pug**视图呈现返回的数据。
视图
创建/views/bookinstance_detail.pug并将下面的内容复制到其中。
extends layout
block content
h1 ID: #{bookinstance._id}
p #[strong Title: ]
a(href=bookinstance.book.url) #{bookinstance.book.title}
p #[strong Imprint:] #{bookinstance.imprint}
p #[strong Status: ]
if bookinstance.status=='Available'
span.text-success #{bookinstance.status}
else if bookinstance.status=='Maintenance'
span.text-danger #{bookinstance.status}
else
span.text-warning #{bookinstance.status}
if bookinstance.status!='Available'
p #[strong Due back:] #{bookinstance.due_back}
此模板中的所有内容都在前面的章节中演示过。
它是什么样子的?
运行应用程序并在浏览器中打开https://127.0.0.1:3000/
。选择“所有图书实例”链接,然后选择其中一项。如果所有设置都正确,您的网站应该看起来像以下屏幕截图。
挑战
目前,网站上显示的大多数日期都使用默认的 JavaScript 格式(例如,Tue Oct 06 2020 15:49:58 GMT+1100 (AUS Eastern Daylight Time))。本文的挑战是改进Author
生命周期信息(死亡/出生日期)和BookInstance 详情页面的日期显示外观,使用格式:Oct 6th, 2016。
注意:您可以使用与Book Instance List中相同的方案(为Author
模型添加生命周期的虚拟属性,并使用luxon格式化日期字符串)。
要完成此挑战,您必须
- 在BookInstance 详情页面中将变量
due_back
替换为due_back_formatted
。 - 更新
Author
模型以添加生命周期的虚拟属性。生命周期应如下所示:date_of_birth - date_of_death,其中两个值的日期格式与BookInstance.due_back_formatted
相同。 - 在所有当前显式使用
date_of_birth
和date_of_death
的视图中使用Author.lifespan
。