图书实例列表页面
接下来,我们将实现图书副本列表(BookInstance
)在图书馆中的展示。此页面需要包含与每个BookInstance
关联的Book
的标题(链接到其详细信息页面),以及BookInstance
模型中的其他信息,包括每份副本的状态、印记和唯一 ID。唯一 ID 文本应链接到BookInstance
的详细信息页面。
控制器
BookInstance
列表控制器函数需要获取所有图书实例的列表,填充关联的图书信息,然后将列表传递给模板进行渲染。
打开/controllers/bookinstanceController.js
。找到导出的bookinstance_list()
控制器方法,并将其替换为以下代码。
// Display list of all BookInstances.
exports.bookinstance_list = asyncHandler(async (req, res, next) => {
const allBookInstances = await BookInstance.find().populate("book").exec();
res.render("bookinstance_list", {
title: "Book Instance List",
bookinstance_list: allBookInstances,
});
});
路由处理程序在BookInstance
模型上调用find()
函数,然后使用book
字段依次调用populate()
- 这将用完整的Book
文档替换每个BookInstance
存储的图书 ID。然后,在末尾依次调用exec()
以执行查询并返回一个 Promise。
路由处理程序使用await
等待 Promise,暂停执行直到其完成。如果 Promise 成功,查询结果将保存到allBookInstances
变量中,并且路由处理程序继续执行。
代码的最后一部分调用render()
,指定bookinstance_list(.pug)模板并将title
和bookinstance_list
的值传递到模板中。
视图
创建/views/bookinstance_list.pug并将下面的文本复制到其中。
extends layout
block content
h1= title
if bookinstance_list.length
ul
each val in bookinstance_list
li
a(href=val.url) #{val.book.title} : #{val.imprint} -
if val.status=='Available'
span.text-success #{val.status}
else if val.status=='Maintenance'
span.text-danger #{val.status}
else
span.text-warning #{val.status}
if val.status!='Available'
span (Due: #{val.due_back} )
else
p There are no book copies in this library.
此视图与所有其他视图非常相似。它扩展了布局,替换了content块,显示从控制器传递的title
,并遍历bookinstance_list
中的所有图书副本。对于每个副本,我们显示其状态(颜色编码),如果图书不可用,则显示其预计归还日期。引入了一项新功能 - 我们可以在标签后使用点表示法来分配类。因此,span.text-success
将编译为<span class="text-success">
(也可以在 Pug 中写成span(class="text-success")
)。
它是什么样子的?
运行应用程序,在浏览器中打开https://127.0.0.1:3000/
,然后选择所有图书实例链接。如果一切设置正确,您的网站应该如下面的屏幕截图所示。
后续步骤
- 返回到Express 教程第 5 部分:显示图书馆数据。
- 继续第 5 部分的下一小节:使用 luxon 进行日期格式化。