diff --git a/files/zh-cn/learn/server-side/express_nodejs/displaying_data/author_detail_page/index.md b/files/zh-cn/learn/server-side/express_nodejs/displaying_data/author_detail_page/index.md index d357fd54a6e3e2..cc87121b853c2b 100644 --- a/files/zh-cn/learn/server-side/express_nodejs/displaying_data/author_detail_page/index.md +++ b/files/zh-cn/learn/server-side/express_nodejs/displaying_data/author_detail_page/index.md @@ -1,63 +1,57 @@ --- -title: 作者细节页面 +title: 作者详情页面 slug: Learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page +l10n: + sourceCommit: 8d5440dbd259fd6eea32b4f4a200f25257d1bf41 --- -作者细节页面需要呈现指定作者`Author`的信息,使用 `_id` 字段的值(自动产生)识别,接着是这个作者的所有书本物件`Book`的列表。 +{{LearnSidebar}} + +作者详情页面需要呈现指定作者(`Author`)的信息,使用(自动生成的)`_id` 字段值进行标识,接着是这个作者的所有书本(`Book`)对象的列表。 ## 控制器 打开 **/controllers/authorController.js**。 -在档案最上方,加入底下几行,引入 async 和 Book 模组 (作者细节页面需要它们)。 +在文件顶部添加以下代码,以此来引入(`require()`)作者详情页所需的 `Book` 模块(其他模块,例如“express-async-handler”应该已经存在)。 ```js -var async = require("async"); -var Book = require("../models/book"); +const Book = require("../models/book"); ``` -找到 exported `author_detail()` 控制器方法,并用底下代码置换。 +找到被导出的 `author_detail()` 控制器方法,并用以下代码替换。 ```js -// Display detail page for a specific Author. -exports.author_detail = function (req, res, next) { - async.parallel( - { - author: function (callback) { - Author.findById(req.params.id).exec(callback); - }, - authors_books: function (callback) { - Book.find({ author: req.params.id }, "title summary").exec(callback); - }, - }, - function (err, results) { - if (err) { - return next(err); - } // Error in API usage. - if (results.author == null) { - // No results. - var err = new Error("Author not found"); - err.status = 404; - return next(err); - } - // Successful, so render. - res.render("author_detail", { - title: "Author Detail", - author: results.author, - author_books: results.authors_books, - }); - }, - ); -}; +// 呈现指定作者的详情页。 +exports.author_detail = asyncHandler(async (req, res, next) => { + // (并行地)获取作者的详细信息及其所有作品 + const [author, allBooksByAuthor] = await Promise.all([ + Author.findById(req.params.id).exec(), + Book.find({ author: req.params.id }, "title summary").exec(), + ]); + + if (author === null) { + // 没有结果。 + const err = new Error("Author not found"); + err.status = 404; + return next(err); + } + + res.render("author_detail", { + title: "Author Detail", + author: author, + author_books: allBooksByAuthor, + }); +}); ``` -此处的控制器方法使用 `async.parallel()`,用平行的方式,查询作者 `Author`和相应的书本实例,并附加上绘制本页面的回调,如果 2 个要求都成功完成,就运行回调。这个方式,就跟前面的种类细节页面所说明的完全相同。 +该方法与[种类详情页面](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Genre_detail_page)中描述的方法完全相同。路由控制器函数使用 `Promise.all()` 并行地查询指定的作者(`Author`)及其关联的 `Book` 实例。如果没有找到匹配的作者,则会将错误(Error)对象发送到 Express 错误处理中间件。如果找到作者,则使用“author_detail”模板呈现检索到的数据库信息。 ## 视图 -创建 **/views/author_detail.pug** ,並複制貼上底下的文字。 +创建 **/views/author_detail.pug** 并复制以下文本。 -```js +```pug extends layout block content @@ -67,30 +61,29 @@ block content div(style='margin-left:20px;margin-top:20px') - h4 Books - - dl - each book in author_books - dt - a(href=book.url) #{book.title} - dd #{book.summary} - - else - p This author has no books. + h2(style='font-size: 1.5rem;') Books + if author_books.length + dl + each book in author_books + dt + a(href=book.url) #{book.title} + dd #{book.summary} + else + p This author has no books. ``` 本模板里的所有事物,都在先前的章节演示过了。 ## 它看起來像是? -运行本应用,并打开浏览器访问 。选择 All Authors 连结,然后选择一个作者。如果每个东西都设定正确了,你的网站看起来应该会像底下的截图。 +运行本应用并打开浏览器访问 `http://localhost:3000/`。选择 _All Authors_ 链接,然后选择一个作者。如果每个配置都设定正确了,你的网站应该类似于下方的截图。 -![Author Detail Page - Express Local Library site](locallibary_express_author_detail.png) +![作者详情页面——Express 本地图书馆网站](locallibary_express_author_detail.png) > [!NOTE] -> 作者的出生与死亡日期的外观很丑!我们将在本文最后的自我挑战处理它。 +> 作者的出生与死亡日期的外观很丑!我们将在本文最后的自我挑战中处理它。 ## 下一步 -- 回到 [Express 教程 5: 呈现图书馆数据](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data) -- 继续教程 5 的下一个部分 : [书本实例细节页面和自我挑战](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_detail_page_and_challenge) +- 回到 [Express 教程 5:呈现图书馆数据](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data) +- 继续教程 5 的下一个部分:[书本实例细节页面和自我挑战](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_detail_page_and_challenge)