圖書詳情頁面

圖書詳情頁 需要顯示特定Book(透過其自動生成的_id 欄位值識別)的資訊,以及圖書館中每本關聯副本(BookInstance)的資訊。無論何時顯示作者、型別或圖書例項,都應將其連結到該項的相應詳情頁。

控制器

開啟 /controllers/bookController.js。找到匯出的 book_detail() 控制器方法,並將其替換為以下程式碼。

js
// 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 並新增以下文字。

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
        |,&nbsp;

  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} 前面的 !,這可確保值不會被轉義顯示。這樣做是因為我們已經以程式設計方式對要顯示的資料進行了清理,再次清理將會顯示我們“清理過的標記”,而不是原始文字的安全版本。我們選擇不對作者、圖書型別等執行相同操作(儘管我們可以這樣做),因為我們不期望它們包含需要清理的任何“危險”字元。

此模板中的幾乎所有其他內容在前幾節中都已演示過。

注意:與圖書關聯的圖書型別列表在模板中實現如下。這會在與圖書關聯的每種圖書型別後新增逗號和不間斷空格,但最後一個除外。

pug
  p #[strong Genre: ]
    each val, index in book.genre
      a(href=val.url) #{val.name}
      if index < book.genre.length - 1
        |,&nbsp;

它看起來怎麼樣?

執行應用程式,並在瀏覽器中開啟 https://:3000/。選擇所有圖書連結,然後選擇其中一本書。如果一切設定正確,您的頁面應類似於以下螢幕截圖。

Book Detail Page - Express Local Library site

後續步驟