Skip to content

Commit

Permalink
convert to markdown for express_nodejs
Browse files Browse the repository at this point in the history
  • Loading branch information
yin1999 committed Jul 31, 2022
1 parent d9346c3 commit 3999b8a
Show file tree
Hide file tree
Showing 28 changed files with 2,904 additions and 2,929 deletions.
655 changes: 321 additions & 334 deletions files/zh-cn/learn/server-side/express_nodejs/deployment/index.md

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,26 @@ title: 作者细节页面
slug: learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page
translation_of: Learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page
---
<p>作者细节页面需要呈现指定作者<code>Author</code>的信息,使用 <code>_id</code> 字段的值(自动产生)识别,接着是这个作者的所有书本物件<code>Book</code>的列表。</p>
作者细节页面需要呈现指定作者`Author`的信息,使用 `_id` 字段的值(自动产生)识别,接着是这个作者的所有书本物件`Book`的列表。

<h2 id="控制器">控制器</h2>
## 控制器

<p>打开 <strong>/controllers/authorController.js</strong>。</p>
打开 **/controllers/authorController.js**

<p>在档案最上方,加入底下几行,引入 async 和 Book 模组 (作者细节页面需要它们)。</p>
在档案最上方,加入底下几行,引入 async 和 Book 模组 (作者细节页面需要它们)。

<pre class="brush: js">var async = require('async');
var Book = require('../models/book');</pre>
```js
var async = require('async');
var Book = require('../models/book');
```

<p>找到 exported <code>author_detail()</code> 控制器方法,并用底下代码置换。</p>
找到 exported `author_detail()` 控制器方法,并用底下代码置换。

<pre class="brush: js">// Display detail page for a specific Author.
```js
// Display detail page for a specific Author.
exports.author_detail = function(req, res, next) {

<strong> async.parallel({
async.parallel({
author: function(callback) {
Author.findById(req.params.id)
.exec(callback)
Expand All @@ -37,22 +40,23 @@ exports.author_detail = function(req, res, next) {
}
// Successful, so render.
res.render('author_detail', { title: 'Author Detail', author: results.author, author_books: results.authors_books } );
});</strong>
});

};
</pre>
```

<p>此处的控制器方法使用 <code>async.parallel()</code>,用平行的方式,查询作者 <code>Author</code>和相应的书本实例,并附加上绘制本页面的回调,如果 2 个要求都成功完成,就运行回调。这个方式,就跟前面的种类细节页面所说明的完全相同。</p>
此处的控制器方法使用 `async.parallel()`,用平行的方式,查询作者 `Author`和相应的书本实例,并附加上绘制本页面的回调,如果 2 个要求都成功完成,就运行回调。这个方式,就跟前面的种类细节页面所说明的完全相同。

<h2 id="视图">视图</h2>
## 视图

<p>创建 <strong>/views/author_detail.pug</strong> ,並複制貼上底下的文字。</p>
创建 **/views/author_detail.pug** ,並複制貼上底下的文字。

<pre class="brush: js">extends layout
```js
extends layout

block content

<strong> h1 Author: #{author.name}</strong>
h1 Author: #{author.name}
p #{author.date_of_birth} - #{author.date_of_death}

div(style='margin-left:20px;margin-top:20px')
Expand All @@ -67,23 +71,19 @@ block content

else
p This author has no books.
</pre>
```

<p>本模板里的所有事物,都在先前的章节演示过了。</p>
本模板里的所有事物,都在先前的章节演示过了。

<h2 id="它看起來像是">它看起來像是?</h2>
## 它看起來像是

<p>运行本应用,并打开浏览器访问 <a href="http://localhost:3000/">http://localhost:3000/</a>。选择 All Authors 连结,然后选择一个作者。如果每个东西都设定正确了,你的网站看起来应该会像底下的截图。</p>
运行本应用,并打开浏览器访问 <http://localhost:3000/>。选择 All Authors 连结,然后选择一个作者。如果每个东西都设定正确了,你的网站看起来应该会像底下的截图。

<p><img alt="Author Detail Page - Express Local Library site" src="locallibary_express_author_detail.png"></p>
![Author Detail Page - Express Local Library site](locallibary_express_author_detail.png)

<div class="note">
<p><strong>备注:</strong> 作者的出生与死亡日期的外观很丑!我们将在本文最后的自我挑战处理它。</p>
</div>
> **备注:** 作者的出生与死亡日期的外观很丑!我们将在本文最后的自我挑战处理它。
<h2 id="下一步">下一步</h2>
## 下一步

<ul>
<li>回到 <a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express 教程 5: 呈现图书馆数据</a></li>
<li>继续教程 5 的下一个部分 : <a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_detail_page_and_challenge"> 书本实例细节页面和自我挑战 </a></li>
</ul>
- 回到 [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)
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ title: 作者清单面页、分类清单页面、与自我挑战
slug: learn/Server-side/Express_Nodejs/Displaying_data/Author_list_page
translation_of: Learn/Server-side/Express_Nodejs/Displaying_data/Author_list_page
---
<p>作者列表页面,需要呈现数据库中所有作者的列表,有每位作者的名字,并连结到作者详细内容页面。出生与死亡日期应该在名字后面,并且在同一列。</p>
作者列表页面,需要呈现数据库中所有作者的列表,有每位作者的名字,并连结到作者详细内容页面。出生与死亡日期应该在名字后面,并且在同一列。

<h2 id="控制器">控制器</h2>
## 控制器

<p>作者列表控制器函数,需要获取所有作者实例的列表,然后将这些实例传递给模板进行渲染。</p>
作者列表控制器函数,需要获取所有作者实例的列表,然后将这些实例传递给模板进行渲染。

<p>打开<strong>/controllers/authorController.js</strong>。在文件顶部附近,找到导出的<code>author_list()</code> 控制器方法,并将其替换为以下代码(更改后的代码以粗体显示)。</p>
打开**/controllers/authorController.js**。在文件顶部附近,找到导出的`author_list()` 控制器方法,并将其替换为以下代码(更改后的代码以粗体显示)。

<pre class="brush: js">// Display list of all Authors.
```js
// Display list of all Authors.
exports.author_list = function(req, res, next) {

Author.find()
Expand All @@ -22,15 +23,17 @@ exports.author_list = function(req, res, next) {
res.render('author_list', { title: 'Author List', author_list: list_authors });
});

};</pre>
};
```

<p>该方法使用模型的 <code>find()</code>, <code>sort()</code><code>exec()</code> 函数,以返回所有<code>Author</code>对象,并按<code>family_name</code>的字母顺排列。传递给<code>exec()</code>方法的回调被调用,并将传入任何错误(或<code>null</code>)作为第一个参数,或者成功时,传入所有作者列表。如果出现错误,则调用带有错误值的下一个中间件函数,如果没有错误,则呈现<strong> author_list</strong>(.pug)模板,传递页面标题<code>title,</code>和作者列表(<code>author_list</code>)。</p>
该方法使用模型的 `find()`, `sort()``exec()` 函数,以返回所有`Author`对象,并按`family_name`的字母顺排列。传递给`exec()`方法的回调被调用,并将传入任何错误(或`null`)作为第一个参数,或者成功时,传入所有作者列表。如果出现错误,则调用带有错误值的下一个中间件函数,如果没有错误,则呈现 **author_list**(.pug)模板,传递页面标题`title,`和作者列表(`author_list`)。

<h2 id="视图">视图</h2>
## 视图

<p>打开 <strong>/views/author_list.pug </strong>,用底下文字取代它的内容。</p>
打开 **/views/author_list.pug** ,用底下文字取代它的内容。

<pre class="brush: js">extends layout
```js
extends layout

block content
h1= title
Expand All @@ -42,48 +45,44 @@ block content
| (#{author.date_of_birth} - #{author.date_of_death})

else
li There are no authors.</pre>
li There are no authors.
```

<p>如同我们其它的模板,上面视图也依照着同样的模式。</p>
如同我们其它的模板,上面视图也依照着同样的模式。

<h2 id="它看起來像是">它看起來像是?</h2>
## 它看起來像是

<p>运行本应用,并打开浏览器访问 <a href="http://localhost:3000/">http://localhost:3000/</a> 。然后选择所有作者 All authors 连结。如果每个东西都设定正确了,页面看起来应该像底下的截图。</p>
运行本应用,并打开浏览器访问 <http://localhost:3000/> 。然后选择所有作者 All authors 连结。如果每个东西都设定正确了,页面看起来应该像底下的截图。

<p><img alt="Author List Page - Express Local Library site" src="locallibary_express_author_list.png"></p>
![Author List Page - Express Local Library site](locallibary_express_author_list.png)

<div class="note">
<p><strong>备注:</strong> 作者生命日期的外观是丑陋的!您可以使用我们用于<code>BookInstance</code> 列表的<a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data#date_formatting">相同方法</a>(将生命周期的虚拟属性,添加到 <code>Author</code> 模型),来改进此方法。</p>
> **备注:** 作者生命日期的外观是丑陋的!您可以使用我们用于`BookInstance` 列表的[相同方法](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data#date_formatting)(将生命周期的虚拟属性,添加到 `Author` 模型),来改进此方法。
>
> 但是,这次缺少日期,除非严格模式生效,否则将忽略对不存在的属性的引用。`moment()`返回当前时间,并且您不希望将缺少的日期格式化为就像今天一样。
>
> 解决此问题的一种方法,是定义返回格式化日期的函数内容,以便返回空字符串,除非日期实际存在。例如:
>
> `return this.date_of_birth ? moment(this.date_of_birth).format('YYYY-MM-DD') : '';`
<p>但是,这次缺少日期,除非严格模式生效,否则将忽略对不存在的属性的引用。<code>moment()</code>返回当前时间,并且您不希望将缺少的日期格式化为就像今天一样。</p>
## 种类列表页面—自我挑战![Edit](/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data$edit#Genre_list_page—challenge!)

<p>解决此问题的一种方法,是定义返回格式化日期的函数内容,以便返回空字符串,除非日期实际存在。例如:</p>
在这个部分,你应该实作你自己的种类列表页面。该页面应显示数据库中所有种类的列表,每个种类都链接到其关联的详细信息页面。预期结果的屏幕截图如下所示。

<p><code>return this.date_of_birth ? moment(this.date_of_birth).format('YYYY-MM-DD') : '';</code></p>
</div>
![Genre List - Express Local Library site](locallibary_express_genre_list.png)

<h2 id="种类列表页面—自我挑战!Edit">种类列表页面—自我挑战!<a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data$edit#Genre_list_page—challenge!">Edit</a></h2>
种类列表控制器功能,需要获取所有种类实例的列表,然后将这些实例传递给模板进行渲染。

<p>在这个部分,你应该实作你自己的种类列表页面。该页面应显示数据库中所有种类的列表,每个种类都链接到其关联的详细信息页面。预期结果的屏幕截图如下所示。</p>
1. 您需要在 **/controllers/genreController.js** 中编辑`genre_list()`
2. 实现方式几乎与`author_list()`控制器完全相同。

<p><img alt="Genre List - Express Local Library site" src="locallibary_express_genre_list.png"></p>
- 按名称以上升顺序,对结果进行排序。

<p>种类列表控制器功能,需要获取所有种类实例的列表,然后将这些实例传递给模板进行渲染。</p>
3. 要呈现的模板,应命名为 **genre_list.pug**
4. 要呈现的模板应该传递变量`title`('Genre List')和种类列表`genre_list`(从`Genre.find()`回调返回)。
5. 该视图应与上面的屏幕截图/要求相匹配(这应该与作者列表视图具有非常相似的结构/格式,除了种类没有日期)。

<ol>
<li>您需要在 <strong>/controllers/genreController.js</strong> 中编辑<code>genre_list()</code>。</li>
<li>实现方式几乎与<code>author_list()</code>控制器完全相同。
<ul>
<li>按名称以上升顺序,对结果进行排序。</li>
</ul>
</li>
<li>要呈现的模板,应命名为 <strong>genre_list.pug</strong>。</li>
<li>要呈现的模板应该传递变量<code>title</code>('Genre List')和种类列表<code>genre_list</code>(从<code>Genre.find()</code>回调返回)。</li>
<li>该视图应与上面的屏幕截图/要求相匹配(这应该与作者列表视图具有非常相似的结构/格式,除了种类没有日期)。</li>
</ol>
## 下一步

<h2 id="下一步">下一步</h2>
回到 [Express 教程 5: 呈现图书馆数据](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data)

<p>回到 <a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express 教程 5: 呈现图书馆数据</a></p>

<p>继续教程 5 下一個部分:<a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Genre_detail_page">种类细节页面</a></p>
继续教程 5 下一個部分:[种类细节页面](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Genre_detail_page)
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ title: 书本详细信息页面
slug: Learn/Server-side/Express_Nodejs/Displaying_data/Book_detail_page
translation_of: Learn/Server-side/Express_Nodejs/Displaying_data/Book_detail_page
---
<p>书本细节页面需要呈现一本指定书本 (<code>Book</code>) 的信息,使用它的 <code>_id</code> 字段值 (自动产生) 做为识别,接着是图书馆中书本实例 (<code>BookInstance</code>) 的信息。无论我们在哪里呈现一个作者、种类、或书本实例,都应该连结到它的细节页面。</p>
书本细节页面需要呈现一本指定书本 (`Book`) 的信息,使用它的 `_id` 字段值 (自动产生) 做为识别,接着是图书馆中书本实例 (`BookInstance`) 的信息。无论我们在哪里呈现一个作者、种类、或书本实例,都应该连结到它的细节页面。

<h2 id="控制器">控制器</h2>
## 控制器

<p>打开 <strong>/controllers/bookController.js</strong>. ,找到 exported <code>book_detail()</code> 控制器方法,用底下的代码置换。</p>
打开 **/controllers/bookController.js**. ,找到 exported `book_detail()` 控制器方法,用底下的代码置换。

<pre class="brush: js">// Display detail page for a specific book.
```js
// Display detail page for a specific book.
exports.book_detail = function(req, res, next) {

<strong> async.parallel({
async.parallel({
book: function(callback) {

Book.findById(req.params.id)
Expand All @@ -34,23 +35,21 @@ exports.book_detail = function(req, res, next) {
}
// Successful, so render.
res.render('book_detail', { title: 'Title', book: results.book, book_instances: results.book_instance } );
});</strong>
});

};
```

</pre>
> **备注:** 我们不需要用 require 导入 async 和 BookInstance,当我们实作主页面控制器的时候,我们就已经引入这些模组。
<div class="note">
<p><strong>备注:</strong> 我们不需要用 require 导入 async 和 BookInstance,当我们实作主页面控制器的时候,我们就已经引入这些模组。</p>
</div>
此处的控制器方法使用 `async.parallel()`,用平行的方式找到 `Book` 以及它的相应复本 (`BookInstances`) 。这样的处理方式,就跟上面的 种类细节页面 所说明的完全相同。

<p>此处的控制器方法使用 <code>async.parallel()</code>,用平行的方式找到 <code>Book</code> 以及它的相应复本 (<code>BookInstances</code>) 。这样的处理方式,就跟上面的 种类细节页面 所说明的完全相同。</p>
## 视图

<h2 id="视图">视图</h2>
创建 **/views/book_detail.pug** 并加入底下文字。

<p>创建 <strong>/views/book_detail.pug</strong> 并加入底下文字。</p>

<pre class="brush: js">extends layout
```js
extends layout

block content
h1 #{title}: #{book.title}
Expand All @@ -59,10 +58,10 @@ block content
a(href=book.author.url) #{book.author.name}
p #[strong Summary:] #{book.summary}
p #[strong ISBN:] #{book.isbn}
p #[strong Genre:]&amp;nbsp;
p #[strong Genre:]&nbsp;
each val, index in book.genre
a(href=val.url) #{val.name}
if index &lt; book.genre.length - 1
if index < book.genre.length - 1
|,

div(style='margin-left:20px;margin-top:20px')
Expand All @@ -71,42 +70,40 @@ block content
each val in book_instances
hr
if val.status=='Available'
<strong>p.text-success</strong> #{val.status}
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:]&amp;nbsp;
p #[strong Id:]&nbsp;
a(href=val.url) #{val._id}

else
p There are no copies of this book in the library.
</pre>

<p>在这个模板里,几乎每个东西都在先前的章节演示过了。</p>
```

<div class="note">
<p><strong>备注:</strong> 与该书相关的種類列表,在模板中的实作,如以下代碼。除了最后一本书之外,在与本书相关的每个种類之后,都会添加一个逗号。</p>
在这个模板里,几乎每个东西都在先前的章节演示过了。

<pre class="brush: plain"> p #[strong Genre:]
each val, index in book.genre
a(href=val.url) #{val.name}
if index &lt; book.genre.length - 1
|, </pre>
</div>
> **备注:** 与该书相关的種類列表,在模板中的实作,如以下代碼。除了最后一本书之外,在与本书相关的每个种類之后,都会添加一个逗号。
>
> ```plain
> p #[strong Genre:]
> each val, index in book.genre
> a(href=val.url) #{val.name}
> if index < book.genre.length - 1
> |,
> ```
<h2 id="它看起來像是">它看起來像是?</h2>
## 它看起來像是

<p>运行本应用,并打开浏览器访问 <a href="http://localhost:3000/">http://localhost:3000/</a>。选择 All books 连结,然后选择其中一本书。如果每个东西都设定正确了,你的页面看起来应该像是底下的截图。</p>
运行本应用,并打开浏览器访问 <http://localhost:3000/>。选择 All books 连结,然后选择其中一本书。如果每个东西都设定正确了,你的页面看起来应该像是底下的截图。

<p><img alt="Book Detail Page - Express Local Library site" src="locallibary_express_book_detail.png"></p>
![Book Detail Page - Express Local Library site](locallibary_express_book_detail.png)

<h2 id="下一步">下一步</h2>
## 下一步

<ul>
<li>回到 <a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express 教程 5: 呈现图书馆数据</a></li>
<li>继续教程 5 的下一个部分:<a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page">作者细节页面</a></li>
</ul>
- 回到 [Express 教程 5: 呈现图书馆数据](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data)
- 继续教程 5 的下一个部分:[作者细节页面](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page)
Loading

0 comments on commit 3999b8a

Please sign in to comment.