2016-02-05 23:27:06 -08:00
|
|
|
|
include ../_util-fns
|
docs(tutorial): combines all 4 sections + revisions/updates to a.53, hides 3&4
closes #488
ToH History (oldest-to-latest):
----------------------------
created code example/snippets files for use with +makeExample, replace usage of "pre.prettyprint.lang-bash" with this: code-example(format="." language="bash").
fixed spelling errors in examples file path used by +makeExample
changed usage of "code-example" to "+makeExample"
adding code example/snippets files used in toh 1
fixed example file paths, replaced "pre.prettyprint.lang-bash" with "code-example. "
(docs) toh-pt3 initial state
created code examples for display in jade, starting conversion of Google doc and trying +makeExample rendering
all text copied from doc to jade, still some styling and formatting to perform
completed conversion and styling, moved toh3 example files to "tutorial" folder under _examples
created specific code example files for chapter toh 3 and re-pathed references in +makeExample
minor edit
docs) toh combined - initial combined commit
updated ToH for a.52
tons of changes, including de-kebab-ing, removed src folder, updated tsconfig too
fixing snippets using incorrect ending input tag
using inline html and css for the app.component.
ToH Part 1 Code: updated the imports, removed obsolete directive delcarations
ToH Code Part 1: updated to use imports, interface. will hit others soon
toh part 1: ngModel fix
toh part1: removed obsolete story that referred to how we used to have to import and declare all directives we used. yay!
ToH Part 1: updated to use `boot.ts` and `app.component.ts`. this affected the partials, snippets, and the story.
toh part 1: using `npm run go`
toh parts 1 -4: modified all places to use `npm run go`
toh part 1: refactor for jade
toh part 1: fixing the code samples
toh part 2: seeping through the story
toh part 2: fixing snippets.
toh part 2: replaced ngClass with class.selected
toh part 2: removed whitespace
toh part 2: added final state to the code
toh: fixing paths
toh part 4: fixing src/app path to app
toh part 3: fixing folder path
toh part 2: fixed typo
toh part 2: typo on ngModel
toh part 2: added ngif
toh part 2: removed old hero property. moved the details lower, where we need it
toh index: updated hero list image to show consistent styling as the other images here
QS spelling error (targes -> targets)
tweeks: space and ngIF
2015-11-15 18:04:43 -08:00
|
|
|
|
|
2015-12-14 20:05:13 -08:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
As the Tour of Heroes app evolves, you'll add more components that need access to hero data.
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
|
|
|
|
随着《英雄指南》的成长,我们要添加更多需要访问英雄数据的组件。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Instead of copying and pasting the same code over and over,
|
|
|
|
|
you'll create a single reusable data service and
|
|
|
|
|
inject it into the components that need it.
|
|
|
|
|
Using a separate service keeps components lean and focused on supporting the view,
|
|
|
|
|
and makes it easy to unit-test components with a mock service.
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
|
|
|
|
为了不再把相同的代码复制一遍又一遍,我们要创建一个单一的可复用的数据服务,并且把它注入到需要它的那些组件中。
|
|
|
|
|
使用单独的服务可以保持组件精简,使其集中精力为视图提供支持,并且,借助模拟(Mock)服务,可以更容易的对组件进行单元测试。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
|
|
|
|
Because data services are invariably asynchronous,
|
2017-03-31 01:13:42 +02:00
|
|
|
|
you'll finish the page with a *Promise*-based version of the data service.
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
|
|
|
|
由于数据服务总是异步的,因此我们最终会提供一个基于承诺(Promise)的数据服务。
|
2016-08-16 10:16:31 +01:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
When you're done with this page, the app should look like this <live-example></live-example>.
|
docs(tutorial): combines all 4 sections + revisions/updates to a.53, hides 3&4
closes #488
ToH History (oldest-to-latest):
----------------------------
created code example/snippets files for use with +makeExample, replace usage of "pre.prettyprint.lang-bash" with this: code-example(format="." language="bash").
fixed spelling errors in examples file path used by +makeExample
changed usage of "code-example" to "+makeExample"
adding code example/snippets files used in toh 1
fixed example file paths, replaced "pre.prettyprint.lang-bash" with "code-example. "
(docs) toh-pt3 initial state
created code examples for display in jade, starting conversion of Google doc and trying +makeExample rendering
all text copied from doc to jade, still some styling and formatting to perform
completed conversion and styling, moved toh3 example files to "tutorial" folder under _examples
created specific code example files for chapter toh 3 and re-pathed references in +makeExample
minor edit
docs) toh combined - initial combined commit
updated ToH for a.52
tons of changes, including de-kebab-ing, removed src folder, updated tsconfig too
fixing snippets using incorrect ending input tag
using inline html and css for the app.component.
ToH Part 1 Code: updated the imports, removed obsolete directive delcarations
ToH Code Part 1: updated to use imports, interface. will hit others soon
toh part 1: ngModel fix
toh part1: removed obsolete story that referred to how we used to have to import and declare all directives we used. yay!
ToH Part 1: updated to use `boot.ts` and `app.component.ts`. this affected the partials, snippets, and the story.
toh part 1: using `npm run go`
toh parts 1 -4: modified all places to use `npm run go`
toh part 1: refactor for jade
toh part 1: fixing the code samples
toh part 2: seeping through the story
toh part 2: fixing snippets.
toh part 2: replaced ngClass with class.selected
toh part 2: removed whitespace
toh part 2: added final state to the code
toh: fixing paths
toh part 4: fixing src/app path to app
toh part 3: fixing folder path
toh part 2: fixed typo
toh part 2: typo on ngModel
toh part 2: added ngif
toh part 2: removed old hero property. moved the details lower, where we need it
toh index: updated hero list image to show consistent styling as the other images here
QS spelling error (targes -> targets)
tweeks: space and ngIF
2015-11-15 18:04:43 -08:00
|
|
|
|
|
2017-04-23 09:34:51 +08:00
|
|
|
|
当我们完成本章的内容是,本应用会变成这样:<live-example></live-example>。
|
docs(tutorial): combines all 4 sections + revisions/updates to a.53, hides 3&4
closes #488
ToH History (oldest-to-latest):
----------------------------
created code example/snippets files for use with +makeExample, replace usage of "pre.prettyprint.lang-bash" with this: code-example(format="." language="bash").
fixed spelling errors in examples file path used by +makeExample
changed usage of "code-example" to "+makeExample"
adding code example/snippets files used in toh 1
fixed example file paths, replaced "pre.prettyprint.lang-bash" with "code-example. "
(docs) toh-pt3 initial state
created code examples for display in jade, starting conversion of Google doc and trying +makeExample rendering
all text copied from doc to jade, still some styling and formatting to perform
completed conversion and styling, moved toh3 example files to "tutorial" folder under _examples
created specific code example files for chapter toh 3 and re-pathed references in +makeExample
minor edit
docs) toh combined - initial combined commit
updated ToH for a.52
tons of changes, including de-kebab-ing, removed src folder, updated tsconfig too
fixing snippets using incorrect ending input tag
using inline html and css for the app.component.
ToH Part 1 Code: updated the imports, removed obsolete directive delcarations
ToH Code Part 1: updated to use imports, interface. will hit others soon
toh part 1: ngModel fix
toh part1: removed obsolete story that referred to how we used to have to import and declare all directives we used. yay!
ToH Part 1: updated to use `boot.ts` and `app.component.ts`. this affected the partials, snippets, and the story.
toh part 1: using `npm run go`
toh parts 1 -4: modified all places to use `npm run go`
toh part 1: refactor for jade
toh part 1: fixing the code samples
toh part 2: seeping through the story
toh part 2: fixing snippets.
toh part 2: replaced ngClass with class.selected
toh part 2: removed whitespace
toh part 2: added final state to the code
toh: fixing paths
toh part 4: fixing src/app path to app
toh part 3: fixing folder path
toh part 2: fixed typo
toh part 2: typo on ngModel
toh part 2: added ngif
toh part 2: removed old hero property. moved the details lower, where we need it
toh index: updated hero list image to show consistent styling as the other images here
QS spelling error (targes -> targets)
tweeks: space and ngIF
2015-11-15 18:04:43 -08:00
|
|
|
|
|
2015-12-14 20:05:13 -08:00
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
## Where you left off
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-08-16 10:16:31 +01:00
|
|
|
|
## 延续上一步教程
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Before continuing with the Tour of Heroes, verify that you have the following structure.
|
|
|
|
|
If not, go back to the previous pages.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
在继续《英雄指南》之前,先检查一下,是否已经有如下目录结构。如果没有,回上一章,看看错过了哪里。
|
docs(tutorial): combines all 4 sections + revisions/updates to a.53, hides 3&4
closes #488
ToH History (oldest-to-latest):
----------------------------
created code example/snippets files for use with +makeExample, replace usage of "pre.prettyprint.lang-bash" with this: code-example(format="." language="bash").
fixed spelling errors in examples file path used by +makeExample
changed usage of "code-example" to "+makeExample"
adding code example/snippets files used in toh 1
fixed example file paths, replaced "pre.prettyprint.lang-bash" with "code-example. "
(docs) toh-pt3 initial state
created code examples for display in jade, starting conversion of Google doc and trying +makeExample rendering
all text copied from doc to jade, still some styling and formatting to perform
completed conversion and styling, moved toh3 example files to "tutorial" folder under _examples
created specific code example files for chapter toh 3 and re-pathed references in +makeExample
minor edit
docs) toh combined - initial combined commit
updated ToH for a.52
tons of changes, including de-kebab-ing, removed src folder, updated tsconfig too
fixing snippets using incorrect ending input tag
using inline html and css for the app.component.
ToH Part 1 Code: updated the imports, removed obsolete directive delcarations
ToH Code Part 1: updated to use imports, interface. will hit others soon
toh part 1: ngModel fix
toh part1: removed obsolete story that referred to how we used to have to import and declare all directives we used. yay!
ToH Part 1: updated to use `boot.ts` and `app.component.ts`. this affected the partials, snippets, and the story.
toh part 1: using `npm run go`
toh parts 1 -4: modified all places to use `npm run go`
toh part 1: refactor for jade
toh part 1: fixing the code samples
toh part 2: seeping through the story
toh part 2: fixing snippets.
toh part 2: replaced ngClass with class.selected
toh part 2: removed whitespace
toh part 2: added final state to the code
toh: fixing paths
toh part 4: fixing src/app path to app
toh part 3: fixing folder path
toh part 2: fixed typo
toh part 2: typo on ngModel
toh part 2: added ngif
toh part 2: removed old hero property. moved the details lower, where we need it
toh index: updated hero list image to show consistent styling as the other images here
QS spelling error (targes -> targets)
tweeks: space and ngIF
2015-11-15 18:04:43 -08:00
|
|
|
|
|
2015-12-14 20:05:13 -08:00
|
|
|
|
.filetree
|
2016-09-20 05:24:40 +02:00
|
|
|
|
.file angular-tour-of-heroes
|
2015-12-14 20:05:13 -08:00
|
|
|
|
.children
|
2017-02-02 18:38:17 +00:00
|
|
|
|
.file src
|
2015-12-14 20:05:13 -08:00
|
|
|
|
.children
|
2017-02-02 18:38:17 +00:00
|
|
|
|
.file app
|
|
|
|
|
.children
|
|
|
|
|
.file app.component.ts
|
|
|
|
|
.file app.module.ts
|
|
|
|
|
.file hero.ts
|
|
|
|
|
.file hero-detail.component.ts
|
2016-02-11 15:08:06 -08:00
|
|
|
|
.file main.ts
|
2017-02-02 18:38:17 +00:00
|
|
|
|
.file index.html
|
|
|
|
|
.file styles.css
|
|
|
|
|
.file systemjs.config.js
|
|
|
|
|
.file tsconfig.json
|
2016-02-11 15:08:06 -08:00
|
|
|
|
.file node_modules ...
|
2015-12-14 20:05:13 -08:00
|
|
|
|
.file package.json
|
2016-06-07 15:51:25 -07:00
|
|
|
|
|
2015-12-14 20:05:13 -08:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
## Keep the app transpiling and running
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
## 让应用代码保持转译和运行
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Enter the following command in the terminal window:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
在终端窗口中输入如下命令:
|
docs(tutorial): combines all 4 sections + revisions/updates to a.53, hides 3&4
closes #488
ToH History (oldest-to-latest):
----------------------------
created code example/snippets files for use with +makeExample, replace usage of "pre.prettyprint.lang-bash" with this: code-example(format="." language="bash").
fixed spelling errors in examples file path used by +makeExample
changed usage of "code-example" to "+makeExample"
adding code example/snippets files used in toh 1
fixed example file paths, replaced "pre.prettyprint.lang-bash" with "code-example. "
(docs) toh-pt3 initial state
created code examples for display in jade, starting conversion of Google doc and trying +makeExample rendering
all text copied from doc to jade, still some styling and formatting to perform
completed conversion and styling, moved toh3 example files to "tutorial" folder under _examples
created specific code example files for chapter toh 3 and re-pathed references in +makeExample
minor edit
docs) toh combined - initial combined commit
updated ToH for a.52
tons of changes, including de-kebab-ing, removed src folder, updated tsconfig too
fixing snippets using incorrect ending input tag
using inline html and css for the app.component.
ToH Part 1 Code: updated the imports, removed obsolete directive delcarations
ToH Code Part 1: updated to use imports, interface. will hit others soon
toh part 1: ngModel fix
toh part1: removed obsolete story that referred to how we used to have to import and declare all directives we used. yay!
ToH Part 1: updated to use `boot.ts` and `app.component.ts`. this affected the partials, snippets, and the story.
toh part 1: using `npm run go`
toh parts 1 -4: modified all places to use `npm run go`
toh part 1: refactor for jade
toh part 1: fixing the code samples
toh part 2: seeping through the story
toh part 2: fixing snippets.
toh part 2: replaced ngClass with class.selected
toh part 2: removed whitespace
toh part 2: added final state to the code
toh: fixing paths
toh part 4: fixing src/app path to app
toh part 3: fixing folder path
toh part 2: fixed typo
toh part 2: typo on ngModel
toh part 2: added ngif
toh part 2: removed old hero property. moved the details lower, where we need it
toh index: updated hero list image to show consistent styling as the other images here
QS spelling error (targes -> targets)
tweeks: space and ngIF
2015-11-15 18:04:43 -08:00
|
|
|
|
|
2016-12-01 08:15:04 -08:00
|
|
|
|
code-example(language="sh" class="code-shell").
|
2015-12-16 21:47:02 -05:00
|
|
|
|
npm start
|
docs(tutorial): combines all 4 sections + revisions/updates to a.53, hides 3&4
closes #488
ToH History (oldest-to-latest):
----------------------------
created code example/snippets files for use with +makeExample, replace usage of "pre.prettyprint.lang-bash" with this: code-example(format="." language="bash").
fixed spelling errors in examples file path used by +makeExample
changed usage of "code-example" to "+makeExample"
adding code example/snippets files used in toh 1
fixed example file paths, replaced "pre.prettyprint.lang-bash" with "code-example. "
(docs) toh-pt3 initial state
created code examples for display in jade, starting conversion of Google doc and trying +makeExample rendering
all text copied from doc to jade, still some styling and formatting to perform
completed conversion and styling, moved toh3 example files to "tutorial" folder under _examples
created specific code example files for chapter toh 3 and re-pathed references in +makeExample
minor edit
docs) toh combined - initial combined commit
updated ToH for a.52
tons of changes, including de-kebab-ing, removed src folder, updated tsconfig too
fixing snippets using incorrect ending input tag
using inline html and css for the app.component.
ToH Part 1 Code: updated the imports, removed obsolete directive delcarations
ToH Code Part 1: updated to use imports, interface. will hit others soon
toh part 1: ngModel fix
toh part1: removed obsolete story that referred to how we used to have to import and declare all directives we used. yay!
ToH Part 1: updated to use `boot.ts` and `app.component.ts`. this affected the partials, snippets, and the story.
toh part 1: using `npm run go`
toh parts 1 -4: modified all places to use `npm run go`
toh part 1: refactor for jade
toh part 1: fixing the code samples
toh part 2: seeping through the story
toh part 2: fixing snippets.
toh part 2: replaced ngClass with class.selected
toh part 2: removed whitespace
toh part 2: added final state to the code
toh: fixing paths
toh part 4: fixing src/app path to app
toh part 3: fixing folder path
toh part 2: fixed typo
toh part 2: typo on ngModel
toh part 2: added ngif
toh part 2: removed old hero property. moved the details lower, where we need it
toh index: updated hero list image to show consistent styling as the other images here
QS spelling error (targes -> targets)
tweeks: space and ngIF
2015-11-15 18:04:43 -08:00
|
|
|
|
|
2015-12-14 20:05:13 -08:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
|
|
|
|
|
The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
|
2017-04-16 21:57:26 +08:00
|
|
|
|
|
|
|
|
|
这个命令会在"监听"模式下运行TypeScript编译器,当代码变化时,它会自动重新编译。
|
|
|
|
|
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.
|
2017-04-16 21:57:26 +08:00
|
|
|
|
|
|
|
|
|
在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
## Creating a hero service
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-04-16 16:43:13 +08:00
|
|
|
|
## 创建英雄服务
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The stakeholders want to show the heroes in various ways on different pages.
|
|
|
|
|
Users can already select a hero from a list.
|
|
|
|
|
Soon you'll add a dashboard with the top performing heroes and create a separate view for editing hero details.
|
|
|
|
|
All three views need hero data.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
客户向我们描绘了本应用更大的目标:想要在不同的页面中用多种方式显示英雄。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
现在我们已经能从列表中选择一个英雄了,但这还不够。
|
|
|
|
|
很快,我们将添加一个仪表盘来显示表现最好的英雄,并创建一个独立视图来编辑英雄的详情。
|
|
|
|
|
所有这些视图都需要英雄数据。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
At the moment, the `AppComponent` defines mock heroes for display.
|
|
|
|
|
However, defining heroes is not the component's job,
|
|
|
|
|
and you can't easily share the list of heroes with other components and views.
|
|
|
|
|
In this page, you'll move the hero data acquisition business to a single service that provides the data and
|
|
|
|
|
share that service with all components that need the data.
|
2015-12-16 21:47:02 -05:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
目前,`AppComponent`显示的是模拟数据。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
不过,定义这些英雄并非组件的任务,否则我们没法与其它组件和视图共享这些英雄列表数据。
|
|
|
|
|
在这一章,我们将把获取英雄数据的任务重构为一个单独的服务,它将提供英雄数据,并把服务在所有需要英雄数据的组件间共享。
|
2015-12-16 21:47:02 -05:00
|
|
|
|
|
|
|
|
|
### Create the HeroService
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
|
|
|
|
### 创建 HeroService
|
|
|
|
|
|
|
|
|
|
Create a file in the `app` folder called `hero.service.ts`.
|
|
|
|
|
|
|
|
|
|
在`app`目录下创建一个名叫`hero.service.ts`的文件。
|
|
|
|
|
|
2015-12-14 20:05:13 -08:00
|
|
|
|
.l-sub-section
|
docs(tutorial): combines all 4 sections + revisions/updates to a.53, hides 3&4
closes #488
ToH History (oldest-to-latest):
----------------------------
created code example/snippets files for use with +makeExample, replace usage of "pre.prettyprint.lang-bash" with this: code-example(format="." language="bash").
fixed spelling errors in examples file path used by +makeExample
changed usage of "code-example" to "+makeExample"
adding code example/snippets files used in toh 1
fixed example file paths, replaced "pre.prettyprint.lang-bash" with "code-example. "
(docs) toh-pt3 initial state
created code examples for display in jade, starting conversion of Google doc and trying +makeExample rendering
all text copied from doc to jade, still some styling and formatting to perform
completed conversion and styling, moved toh3 example files to "tutorial" folder under _examples
created specific code example files for chapter toh 3 and re-pathed references in +makeExample
minor edit
docs) toh combined - initial combined commit
updated ToH for a.52
tons of changes, including de-kebab-ing, removed src folder, updated tsconfig too
fixing snippets using incorrect ending input tag
using inline html and css for the app.component.
ToH Part 1 Code: updated the imports, removed obsolete directive delcarations
ToH Code Part 1: updated to use imports, interface. will hit others soon
toh part 1: ngModel fix
toh part1: removed obsolete story that referred to how we used to have to import and declare all directives we used. yay!
ToH Part 1: updated to use `boot.ts` and `app.component.ts`. this affected the partials, snippets, and the story.
toh part 1: using `npm run go`
toh parts 1 -4: modified all places to use `npm run go`
toh part 1: refactor for jade
toh part 1: fixing the code samples
toh part 2: seeping through the story
toh part 2: fixing snippets.
toh part 2: replaced ngClass with class.selected
toh part 2: removed whitespace
toh part 2: added final state to the code
toh: fixing paths
toh part 4: fixing src/app path to app
toh part 3: fixing folder path
toh part 2: fixed typo
toh part 2: typo on ngModel
toh part 2: added ngif
toh part 2: removed old hero property. moved the details lower, where we need it
toh index: updated hero list image to show consistent styling as the other images here
QS spelling error (targes -> targets)
tweeks: space and ngIF
2015-11-15 18:04:43 -08:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The naming convention for service files is the service name in lowercase followed by `.service`.
|
|
|
|
|
For a multi-word service name, use lower [dash-case](../guide/glossary.html#!#dash-case).
|
|
|
|
|
For example, the filename for `SpecialSuperHeroService` is `special-super-hero.service.ts`.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们遵循的文件命名约定是:服务名称的小写形式(基本名),加上`.service`后缀。
|
|
|
|
|
如果服务名称包含多个单词,我们就把基本名部分写成中线形式 ([dash-case](../guide/glossary.html#dash-case))。
|
|
|
|
|
例如,`SpecialSuperHeroService`服务应该被定义在`special-super-hero.service.ts`文件中。
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Name the class `HeroService` and export it for others to import.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们把这个类命名为`HeroService`,并导出它,以供别人使用。
|
2015-12-16 21:47:02 -05:00
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/hero.service.1.ts', 'empty-class', 'src/app/hero.service.ts (starting point)')(format=".")
|
2015-12-14 20:05:13 -08:00
|
|
|
|
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
### Injectable services
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-04-16 16:43:13 +08:00
|
|
|
|
### 可注入的服务
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Notice that you imported the Angular `Injectable` function and applied that function as an `@Injectable()` decorator.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
注意,我们导入了 Angular 的`Injectable`函数,并作为`@Injectable()`装饰器使用这个函数。
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
.callout.is-helpful
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Don't forget the parentheses. Omitting them leads to an error that's difficult to diagnose.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-05-12 17:50:14 +08:00
|
|
|
|
**不要忘了写圆括号!**如果忘了写,就会导致一个很难诊断的错误。
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The `@Injectable()` decorator tells TypeScript to emit metadata about the service.
|
|
|
|
|
The metadata specifies that Angular may need to inject other dependencies into this service.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
当 TypeScript 看到`@Injectable()`装饰器时,就会记下本服务的元数据。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
如果 Angular 需要往这个服务中注入其它依赖,就会使用这些元数据。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Although the `HeroService` doesn't have any dependencies at the moment,
|
|
|
|
|
applying the `@Injectable()` decorator from the start ensures
|
|
|
|
|
consistency and future-proofing.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
虽然*此时*`HeroService`还没有任何依赖,但我们还是得加上这个装饰器。
|
2016-12-02 02:15:34 +08:00
|
|
|
|
作为一项最佳实践,无论是出于提高统一性还是减少变更的目的,
|
|
|
|
|
都应该从一开始就加上`@Injectable()`装饰器。
|
2015-12-14 20:05:13 -08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
### Getting hero data
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
### 获取英雄数据
|
|
|
|
|
|
2017-03-23 18:47:55 -04:00
|
|
|
|
Add a `getHeroes()` method stub.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-05-12 17:50:14 +08:00
|
|
|
|
添加一个名叫`getHeros`的桩方法。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/hero.service.1.ts', 'getHeroes-stub', 'src/app/hero.service.ts (getHeroes stub)')(format=".")
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The `HeroService` could get `Hero` data from anywhere—a
|
|
|
|
|
web service, local storage, or a mock data source.
|
|
|
|
|
Removing data access from the component means
|
|
|
|
|
you can change your mind about the implementation anytime,
|
|
|
|
|
without touching the components that need hero data.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
`HeroService`可以从任何地方获取`Hero`数据 —— Web服务、本地存储或模拟数据源。
|
|
|
|
|
从组件中移除数据访问逻辑意味着你可以随时更改这些实现方式,而不影响需要这些英雄数据的组件。
|
2016-04-16 16:43:13 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
### Move the mock hero data
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
### 移动模拟的英雄数据
|
|
|
|
|
|
2015-12-23 09:42:57 -08:00
|
|
|
|
Cut the `HEROES` array from `app.component.ts` and paste it to a new file in the `app` folder named `mock-heroes.ts`.
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Additionally, copy the `import {Hero} ...` statement because the heroes array uses the `Hero` class.
|
2015-12-16 21:47:02 -05:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
从`app.component.ts`文件中剪切`HEROS`数组,把它粘贴到`app`目录下一个名叫`mock-heroes.ts`的文件中。
|
|
|
|
|
还要复制`import {Hero}...`语句,因为我们的英雄数组用到了`Hero`类。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/mock-heroes.ts', null, 'src/app/mock-heroes.ts')
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The `HEROES` constant is exported so it can be imported elsewhere, such as the `HeroService`.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们导出了`HEROES`常量,以便可以在其它地方导入它 — 例如`HeroService`服务。
|
2015-12-14 20:05:13 -08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
In `app.component.ts`, where you cut the `HEROES` array,
|
|
|
|
|
add an uninitialized `heroes` property:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
在刚刚剪切出`HEROES`数组的`app.component.ts`文件中,添加一个尚未初始化的`heroes`属性:
|
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/app.component.1.ts', 'heroes-prop', 'src/app/app.component.ts (heroes property)')(format=".")
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
### Return mocked hero data
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-04-16 16:43:13 +08:00
|
|
|
|
### 返回模拟的英雄数据
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-23 18:47:55 -04:00
|
|
|
|
Back in the `HeroService`, import the mock `HEROES` and return it from the `getHeroes()` method.
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The `HeroService` looks like this:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-05-12 17:50:14 +08:00
|
|
|
|
回到`HeroService`,我们导入`HEROES`常量,并在`getHeroes`方法中返回它。
|
2017-04-25 15:50:47 +08:00
|
|
|
|
我们的`HeroService`服务现在是这样的:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/hero.service.1.ts', 'full', 'src/app/hero.service.ts')(format=".")
|
2015-12-14 20:05:13 -08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
### Import the hero service
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
### 导入HeroService
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
You're ready to use the `HeroService` in other components, starting with `AppComponent`.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们可以在多个组件中使用 HeroService 服务了,先从 AppComponent 开始。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Import the `HeroService` so that you can reference it in the code.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
先导入`HeroService`,以便我们可以在代码中引用它。
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
+makeExcerpt('toh-4/ts/src/app/app.component.ts', 'hero-service-import', 'src/app/app.component.ts')
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
### Don't use *new* with the *HeroService*
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
### 不要`new`出`HeroService`
|
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
How should the `AppComponent` acquire a runtime concrete `HeroService` instance?
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
该如何在运行中获得一个具体的`HeroService`实例呢?
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
You could create a new instance of the `HeroService` with `new` like this:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
你可能想用`new`来创建`HeroService`的实例,就像这样:
|
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/app.component.1.ts', 'new-service')(format=".")
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
However, this option isn't ideal for the following reasons:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
但这不是个好主意,有很多理由,例如:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
* The component has to know how to create a `HeroService`.
|
|
|
|
|
If you change the `HeroService` constructor,
|
|
|
|
|
you must find and update every place you created the service.
|
|
|
|
|
Patching code in multiple places is error prone and adds to the test burden.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们的组件得弄清楚该如何创建`HeroService`。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
如果有一天我们修改了`HeroService`的构造函数,我们不得不找出创建过此服务的每一处代码,并修改它。
|
|
|
|
|
围着补丁代码转圈很容易导致错误,还会增加测试负担。
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
* You create a service each time you use `new`.
|
|
|
|
|
What if the service caches heroes and shares that cache with others?
|
|
|
|
|
You couldn't do that.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们每次使用`new`都会创建一个新的服务实例。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
如果这个服务需要缓存英雄列表,并把这个缓存共享给别人呢?怎么办?
|
|
|
|
|
没办法,做不到。
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
* With the `AppComponent` locked into a specific implementation of the `HeroService`,
|
|
|
|
|
switching implementations for different scenarios, such as operating offline or using
|
|
|
|
|
different mocked versions for testing, would be difficult.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们把`AppComponent`锁定到`HeroService`的一个特定实现。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
我们很难在不同的场景中切换实现。
|
|
|
|
|
例如,能离线操作吗?能在测试时使用不同的模拟版本吗?这可不容易。
|
2016-04-16 16:43:13 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
### Inject the *HeroService*
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-04-16 16:43:13 +08:00
|
|
|
|
### 注入 *HeroService*
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Instead of using the *new* line, you'll add two lines.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
你可以用两行代码代替用`new`时的一行:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
* Add a constructor that also defines a private property.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
添加一个构造函数,并定义一个私有属性。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
* Add to the component's `providers` metadata.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
添加组件的`providers`元数据。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Add the constructor:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
添加构造函数:
|
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/app.component.1.ts', 'ctor', 'src/app/app.component.ts (constructor)')
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The constructor itself does nothing. The parameter simultaneously
|
2016-05-03 14:06:32 +02:00
|
|
|
|
defines a private `heroService` property and identifies it as a `HeroService` injection site.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-05-19 13:33:02 +08:00
|
|
|
|
构造函数自己什么也不用做,它在参数中定义了一个私有的`heroService`属性,并把它标记为注入`HeroService`的靶点。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-14 20:05:13 -08:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Now Angular knows to supply an instance of the `HeroService` when it creates an `AppComponent`.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
现在,当创建`AppComponent`实例时,Angular 知道需要先提供一个`HeroService`的实例。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Read more about dependency injection in the [Dependency Injection](../guide/dependency-injection.html) page.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
更多依赖注入的信息,见[依赖注入](../guide/dependency-injection.html)。
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The *injector* doesn't know yet how to create a `HeroService`.
|
|
|
|
|
If you ran the code now, Angular would fail with this error:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-05-12 17:50:14 +08:00
|
|
|
|
*注入器*还不知道该如何创建`HeroService`。
|
2016-12-02 02:15:34 +08:00
|
|
|
|
如果现在运行我们的代码,Angular 就会失败,并报错:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-06-09 12:18:01 -07:00
|
|
|
|
code-example(format="nocode").
|
2015-12-14 20:05:13 -08:00
|
|
|
|
EXCEPTION: No provider for HeroService! (AppComponent -> HeroService)
|
2016-12-02 02:15:34 +08:00
|
|
|
|
(异常:没有 HeroService 的提供商!(AppComponent -> HeroService))
|
2016-06-15 23:31:28 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
To teach the injector how to make a `HeroService`,
|
|
|
|
|
add the following `providers` array property to the bottom of the component metadata
|
2015-12-16 21:47:02 -05:00
|
|
|
|
in the `@Component` call.
|
2015-12-14 20:05:13 -08:00
|
|
|
|
|
2016-07-07 08:22:36 +08:00
|
|
|
|
我们还得注册一个`HeroService`**提供商**,来告诉*注入器*如何创建`HeroService`。
|
2016-12-02 02:15:34 +08:00
|
|
|
|
要做到这一点,我们在`@Component`组件的元数据底部添加`providers`数组属性如下:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
+makeExcerpt('toh-4/ts/src/app/app.component.1.ts', 'providers', 'src/app/app.component.ts')
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The `providers` array tells Angular to create a fresh instance of the `HeroService` when it creates an `AppComponent`.
|
|
|
|
|
The `AppComponent`, as well as its child components, can use that service to get hero data.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
`providers`数组告诉 Angular,当它创建新的`AppComponent`组件时,也要创建一个`HeroService`的新实例。
|
2016-08-23 10:21:32 +01:00
|
|
|
|
`AppComponent`会使用那个服务来获取英雄列表,在它组件树中的每一个子组件也同样如此。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-05-10 19:49:54 +02:00
|
|
|
|
a#child-component
|
2015-12-14 20:05:13 -08:00
|
|
|
|
:marked
|
2017-03-23 18:47:55 -04:00
|
|
|
|
### *getHeroes()* in the *AppComponent*
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
### *AppComponent* 中的 *getHeroes()*
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The service is in a `heroService` private variable.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
该服务被存入了一个私有变量`heroService`中。
|
2017-03-21 11:08:09 -07:00
|
|
|
|
|
|
|
|
|
You could call the service and get the data in one line.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
我们可以在同一行内调用此服务,并获得数据。
|
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/app.component.1.ts', 'get-heroes')(format=".")
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
You don't really need a dedicated method to wrap one line. Write it anyway:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-04-17 10:24:39 +08:00
|
|
|
|
在真实的世界中,我们并不需要把一行代码包装成一个专门的方法,但无论如何,我们在演示代码中先这么写:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
+makeExcerpt('toh-4/ts/src/app/app.component.1.ts', 'getHeroes', 'src/app/app.component.ts')
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2016-03-16 23:49:55 +01:00
|
|
|
|
<a id="oninit"></a>
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
### The *ngOnInit* lifecycle hook
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-11-22 20:07:16 +08:00
|
|
|
|
### *ngOnInit* 生命周期钩子
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
`AppComponent` should fetch and display hero data with no issues.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-04-17 10:24:39 +08:00
|
|
|
|
毫无疑问,`AppComponent`应该获取英雄数据并显示它。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-23 18:47:55 -04:00
|
|
|
|
You might be tempted to call the `getHeroes()` method in a constructor, but
|
2017-03-21 11:08:09 -07:00
|
|
|
|
a constructor should not contain complex logic,
|
|
|
|
|
especially a constructor that calls a server, such as as a data access method.
|
|
|
|
|
The constructor is for simple initializations, like wiring constructor parameters to properties.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
你可能想在构造函数中调用`getHeroes()`方法,但构造函数不应该包含复杂的逻辑,特别是那些需要从服务器获取数据的逻辑更是如此。构造函数是为了简单的初始化工作而设计的,例如把构造函数的参数赋值给属性。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-23 18:47:55 -04:00
|
|
|
|
To have Angular call `getHeroes()`, you can implement the Angular *ngOnInit lifecycle hook*.
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Angular offers interfaces for tapping into critical moments in the component lifecycle:
|
2015-12-16 21:47:02 -05:00
|
|
|
|
at creation, after each change, and at its eventual destruction.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
只要我们实现了 Angular 的 **ngOnInit** *生命周期钩子*,Angular 就会主动调用这个钩子。
|
2016-04-17 10:24:39 +08:00
|
|
|
|
Angular提供了一些接口,用来介入组件生命周期的几个关键时间点:刚创建时、每次变化时,以及最终被销毁时。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
Each interface has a single method. When the component implements that method, Angular calls it at the appropriate time.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
每个接口都有唯一的一个方法。只要组件实现了这个方法,Angular 就会在合适的时机调用它。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Read more about lifecycle hooks in the [Lifecycle Hooks](../guide/lifecycle-hooks.html) page.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
更多生命周期钩子信息,见[生命周期钩子](../guide/lifecycle-hooks.html)。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Here's the essential outline for the `OnInit` interface (don't copy this into your code):
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-16 17:04:44 +08:00
|
|
|
|
这是`OnInit`接口的基本轮廓(但不要拷贝到你自己的代码中):
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
+makeExample('toh-4/ts/src/app/app.component.1.ts', 'on-init')(format=".")
|
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Add the implementation for the `OnInit` interface to your export statement:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
往export语句中添加`OnInit`接口的实现:
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
code-example(format="nocode").
|
|
|
|
|
export class AppComponent implements OnInit {}
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Write an `ngOnInit` method with the initialization logic inside. Angular will call it
|
2017-03-23 18:47:55 -04:00
|
|
|
|
at the right time. In this case, initialize by calling `getHeroes()`.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们写了一个带有初始化逻辑的`ngOnInit`方法,Angular会在适当的时候调用它。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
在这个例子中,我们通过调用`getHeroes()`来完成初始化。
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
+makeExcerpt('toh-4/ts/src/app/app.component.1.ts', 'ng-on-init', 'app/app.component.ts')
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The app should run as expected, showing a list of heroes and a hero detail view
|
|
|
|
|
when you click on a hero name.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-04-17 10:24:39 +08:00
|
|
|
|
我们的应用将会像期望的那样运行,显示英雄列表,并且在我们点击英雄的名字时,显示英雄的详情。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
<a id="async"></a>
|
|
|
|
|
:marked
|
2017-03-31 01:13:42 +02:00
|
|
|
|
## Async services and Promises
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-11-06 12:02:36 +08:00
|
|
|
|
## 异步服务与承诺
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The `HeroService` returns a list of mock heroes immediately;
|
2017-03-23 18:47:55 -04:00
|
|
|
|
its `getHeroes()` signature is synchronous.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
我们的`HeroService`立即返回一个模拟的英雄列表,它的`getHeroes()`函数签名是同步的。
|
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/app.component.1.ts', 'get-heroes')(format=".")
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Eventually, the hero data will come from a remote server.
|
2017-03-23 18:47:55 -04:00
|
|
|
|
When using a remote server, users don't have to wait for the server to respond;
|
|
|
|
|
additionally, you aren't able to block the UI during the wait.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
但最终,英雄的数据会从远端服务器获取。当使用远端服务器时,用户不会等待服务器的响应。换句话说,你没法在等待期间阻塞浏览器界面。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
:marked
|
2017-03-23 18:47:55 -04:00
|
|
|
|
To coordinate the view with the response,
|
2017-03-31 01:13:42 +02:00
|
|
|
|
you can use *Promises*, which is an asynchronous
|
2017-03-23 18:47:55 -04:00
|
|
|
|
technique that changes the signature of the `getHeroes()` method.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
为了协调视图与响应,我们可以使用*承诺(Promise)*,它是一种异步技术,它会改变`getHeroes()`方法的签名。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-31 01:13:42 +02:00
|
|
|
|
### The hero service makes a Promise
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-11-06 12:02:36 +08:00
|
|
|
|
### `HeroService`会生成一个承诺
|
2015-12-16 21:47:02 -05:00
|
|
|
|
|
2017-03-31 01:13:42 +02:00
|
|
|
|
A *Promise* essentially promises to call back when the results are ready.
|
2017-03-21 11:08:09 -07:00
|
|
|
|
You ask an asynchronous service to do some work and give it a callback function.
|
|
|
|
|
The service does that work and eventually calls the function with the results or an error.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
**承诺** 就是 …… 好吧,它就是一个承诺,在有了结果时,它承诺会回调我们。
|
2016-11-06 05:38:34 +08:00
|
|
|
|
我们请求一个异步服务去做点什么,并且给它一个回调函数。
|
2016-12-02 02:15:34 +08:00
|
|
|
|
它会去做(在某个地方),一旦完成,它就会调用我们的回调函数,并通过参数把工作结果或者错误信息传给我们。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
This is a simplified explanation. Read more about ES2015 Promises in the
|
|
|
|
|
[Promises for asynchronous programming](http://exploringjs.com/es6/ch_promises.html) page of
|
|
|
|
|
[Exploring ES6](http://http://exploringjs.com/es6.html).
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
这里只是粗略说说,要了解更多 ES2015 Promise 的信息,见[ES6概览](http://http://exploringjs.com/es6.html)中的[承诺与异步编程](http://exploringjs.com/es6/ch_promises.html)。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-31 01:13:42 +02:00
|
|
|
|
Update the `HeroService` with this Promise-returning `getHeroes()` method:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-11-06 12:02:36 +08:00
|
|
|
|
把`HeroService`的`getHeroes`方法改写为返回承诺的形式:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/hero.service.ts', 'get-heroes', 'src/app/hero.service.ts (excerpt)')(format=".")
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
You're still mocking the data. You're simulating the behavior of an ultra-fast, zero-latency server,
|
2017-03-31 01:13:42 +02:00
|
|
|
|
by returning an *immediately resolved Promise* with the mock heroes as the result.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-11-06 12:02:36 +08:00
|
|
|
|
我们继续使用模拟数据。我们通过返回一个 *立即解决的承诺* 的方式,模拟了一个超快、零延迟的超级服务器。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-31 01:13:42 +02:00
|
|
|
|
### Act on the Promise
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-11-06 12:02:36 +08:00
|
|
|
|
### 基于承诺的行动
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-31 01:13:42 +02:00
|
|
|
|
As a result of the change to `HeroService`, `this.heroes` is now set to a `Promise` rather than an array of heroes.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
修改`HeroService`之后,`this.heroes`会被赋值为一个`Promise`而不再是英雄数组。
|
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/app.component.1.ts', 'getHeroes', 'src/app/app.component.ts (getHeroes - old)')(format=".")
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-31 01:13:42 +02:00
|
|
|
|
You have to change the implementation to *act on the `Promise` when it resolves*.
|
|
|
|
|
When the `Promise` resolves successfully, you'll have heroes to display.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-11-06 12:02:36 +08:00
|
|
|
|
我们得修改这个实现,把它变成*基于承诺*的,并在承诺的事情被解决时再行动。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
一旦承诺的事情被成功解决(Resolve),我们就会显示英雄数据。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-31 01:13:42 +02:00
|
|
|
|
Pass the callback function as an argument to the Promise's `then()` method:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们把回调函数作为参数传给承诺对象的**then**方法:
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeExample('toh-4/ts/src/app/app.component.ts', 'get-heroes', 'src/app/app.component.ts (getHeroes - revised)')(format=".")
|
2015-12-22 10:25:30 -08:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
As described in [Arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions),
|
|
|
|
|
the ES2015 arrow function
|
|
|
|
|
in the callback is more succinct than the equivalent function expression and gracefully handles `this`.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
回调中所用的 [ES2015 箭头函数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
|
|
|
|
|
比等价的函数表达式更加简洁,能优雅的处理 *this* 指针。
|
2017-04-16 22:04:21 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The callback sets the component's `heroes` property to the array of heroes returned by the service.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
在回调函数中,我们把服务返回的英雄数组赋值给组件的`heroes`属性。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The app is still running, showing a list of heroes, and
|
2015-12-16 21:47:02 -05:00
|
|
|
|
responding to a name selection with a detail view.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-25 19:50:45 +01:00
|
|
|
|
我们的程序仍在运行,仍在显示英雄列表,在选择英雄时,仍然会把它/她显示在详情页面中。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
At the end of this page, [Appendix: take it slow](#slow) describes what the app might be like with a poor connection.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-16 22:04:21 +08:00
|
|
|
|
查看附录中的“[慢!](#slow)”,来了解在较差的网络连接中这个应用会是什么样的。
|
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
## Review the app structure
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
## 回顾本应用的结构
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Verify that you have the following structure after all of your refactoring:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
再检查下,经历了本章的所有重构之后,应该有了下列文件结构:
|
2015-12-14 20:05:13 -08:00
|
|
|
|
|
|
|
|
|
.filetree
|
2016-09-20 05:24:40 +02:00
|
|
|
|
.file angular-tour-of-heroes
|
2015-12-14 20:05:13 -08:00
|
|
|
|
.children
|
2017-02-02 18:38:17 +00:00
|
|
|
|
.file src
|
2015-12-14 20:05:13 -08:00
|
|
|
|
.children
|
2017-02-02 18:38:17 +00:00
|
|
|
|
.file app
|
|
|
|
|
.children
|
|
|
|
|
.file app.component.ts
|
|
|
|
|
.file app.module.ts
|
|
|
|
|
.file hero.ts
|
|
|
|
|
.file hero-detail.component.ts
|
|
|
|
|
.file hero.service.ts
|
|
|
|
|
.file mock-heroes.ts
|
|
|
|
|
.file main.ts
|
|
|
|
|
.file index.html
|
|
|
|
|
.file styles.css
|
|
|
|
|
.file systemjs.config.js
|
|
|
|
|
.file tsconfig.json
|
2017-03-21 11:08:09 -07:00
|
|
|
|
.file node_modules ...
|
2015-12-14 20:05:13 -08:00
|
|
|
|
.file package.json
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Here are the code files discussed in this page.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
下面是本章讨论过的代码文件:
|
2015-12-16 21:47:02 -05:00
|
|
|
|
|
|
|
|
|
+makeTabs(`
|
2017-02-02 18:38:17 +00:00
|
|
|
|
toh-4/ts/src/app/hero.service.ts,
|
|
|
|
|
toh-4/ts/src/app/app.component.ts,
|
|
|
|
|
toh-4/ts/src/app/mock-heroes.ts
|
2015-12-16 21:47:02 -05:00
|
|
|
|
`,'',`
|
2017-02-02 18:38:17 +00:00
|
|
|
|
src/app/hero.service.ts,
|
|
|
|
|
src/app/app.component.ts,
|
|
|
|
|
src/app/mock-heroes.ts
|
2015-12-16 21:47:02 -05:00
|
|
|
|
`)
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
## The road you've travelled
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-04-17 10:24:39 +08:00
|
|
|
|
## 走过的路
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Here's what you achieved in this page:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
来盘点一下我们完成了什么。
|
2015-12-14 20:05:13 -08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
* You created a service class that can be shared by many components.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们创建了一个能被多个组件共享的服务类。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
* You used the `ngOnInit` lifecycle hook to get the hero data when the `AppComponent` activates.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们使用了`ngOnInit`生命周期钩子,以便在`AppComponent`激活时获取英雄数据。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
* You defined the `HeroService` as a provider for the `AppComponent`.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们把`HeroService`定义为`AppComponent`的一个提供商。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
* You created mock hero data and imported them into the service.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们创建了模拟的英雄数据,并把它导入我们的服务中。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-31 01:13:42 +02:00
|
|
|
|
* You designed the service to return a Promise and the component to get the data from the Promise.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-04-16 22:04:21 +08:00
|
|
|
|
我们把服务设计为返回承诺,组件从承诺中获取数据。
|
2015-12-14 20:05:13 -08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
Your app should look like this <live-example></live-example>.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
现在应用变成了这样:<live-example></live-example>。
|
2015-12-16 21:47:02 -05:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
## The road ahead
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
## 前方的路
|
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
The Tour of Heroes has become more reusable using shared components and services.
|
|
|
|
|
The next goal is to create a dashboard, add menu links that route between the views, and format data in a template.
|
2017-03-23 18:47:55 -04:00
|
|
|
|
As the app evolves, you'll discover how to design it to make it easier to grow and maintain.
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2016-05-12 17:50:14 +08:00
|
|
|
|
通过使用共享组件和服务,我们的《英雄指南》更有复用性了。
|
2017-04-15 15:34:47 +08:00
|
|
|
|
我们还要创建一个仪表盘,要添加在视图间路由的菜单链接,还要在模板中格式化数据。
|
|
|
|
|
随着我们应用的进化,我们还会学到如何进行设计,让它更易于扩展和维护。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-23 18:47:55 -04:00
|
|
|
|
Read about the Angular component router and navigation among the views in the [next tutorial](toh-pt5.html) page.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-12-02 02:15:34 +08:00
|
|
|
|
我们将在[下一章](toh-pt5.html)学习 Angular 组件路由,以及在视图间导航的知识。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
.l-main-section
|
|
|
|
|
<a id="slow"></a>
|
|
|
|
|
:marked
|
2017-03-21 11:08:09 -07:00
|
|
|
|
## Appendix: Take it slow
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-04-16 22:04:21 +08:00
|
|
|
|
## 附件:慢
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
To simulate a slow connection,
|
2017-03-23 18:47:55 -04:00
|
|
|
|
import the `Hero` symbol and add the following `getHeroesSlowly()` method to the `HeroService`.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
我们可以模拟慢速连接。导入`Hero`类,并且在`HeroService`中添加如下的`getHeroesSlowly()`方法:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-21 11:08:09 -07:00
|
|
|
|
+makeExample('toh-4/ts/src/app/hero.service.ts', 'get-heroes-slowly', 'app/hero.service.ts (getHeroesSlowly)')(format=".")
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2015-12-16 21:47:02 -05:00
|
|
|
|
:marked
|
2017-03-31 01:13:42 +02:00
|
|
|
|
Like `getHeroes()`, it also returns a `Promise`.
|
|
|
|
|
But this Promise waits two seconds before resolving the Promise with mock heroes.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-16 17:04:44 +08:00
|
|
|
|
像`getHeroes()`一样,它也返回一个承诺。
|
2016-11-06 12:02:36 +08:00
|
|
|
|
但是,这个承诺会在提供模拟数据之前等待两秒钟。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-23 18:47:55 -04:00
|
|
|
|
Back in the `AppComponent`, replace `getHeroes()` with `getHeroesSlowly()`
|
2015-12-16 21:47:02 -05:00
|
|
|
|
and see how the app behaves.
|
2016-06-13 17:22:28 +08:00
|
|
|
|
|
2017-04-16 17:04:44 +08:00
|
|
|
|
回到`AppComponent`,用`heroService.getHeroesSlowly()`替换`heroService.getHeroes()`,并观察应用的行为。
|