图书实例列表页面

接下来,我们将实现图书副本列表(BookInstance)在图书馆中的展示。此页面需要包含与每个BookInstance关联的Book的标题(链接到其详细信息页面),以及BookInstance模型中的其他信息,包括每份副本的状态、印记和唯一 ID。唯一 ID 文本应链接到BookInstance的详细信息页面。

控制器

BookInstance列表控制器函数需要获取所有图书实例的列表,填充关联的图书信息,然后将列表传递给模板进行渲染。

打开/controllers/bookinstanceController.js。找到导出的bookinstance_list()控制器方法,并将其替换为以下代码。

js
// 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)模板并将titlebookinstance_list的值传递到模板中。

视图

创建/views/bookinstance_list.pug并将下面的文本复制到其中。

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/,然后选择所有图书实例链接。如果一切设置正确,您的网站应该如下面的屏幕截图所示。

BookInstance List Page - Express Local Library site

后续步骤