对上次的合并查漏补缺

This commit is contained in:
Zhicheng Wang 2016-09-10 20:44:57 +08:00
parent ab06793705
commit 8a7165acf5
5 changed files with 162 additions and 12 deletions

View File

@ -721,7 +721,7 @@ block hero-list-comp-add-hero
It's easy to do and a promise-based version looks much like the observable-based version in simple cases.
虽然Angular的`http`客户端API返回的是`Observable<Response>`类型的对象,但我们也可以把它转成
[Promise<Response>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)。
[`Promise<Response>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)。
这很容易,并且在简单的场景中,一个基于承诺(Promise)的版本看起来很像基于可观察对象(Observable)的版本。
.l-sub-section
:marked

View File

@ -698,8 +698,8 @@ p.
p.
<code>app.component.html</code>显示了这个可下载的Angular Logo
<a href="https://raw.githubusercontent.com/angular/angular.io/master/public/resources/images/logos/angular2/angular.png" target="_blank">
<img src="https://raw.githubusercontent.com/angular/angular.io/master/public/resources/images/logos/angular2/angular.png" height="40px" title="download Angular logo"></a>。
<a href="/resources/images/logos/angular2/angular.png" target="_blank">
<img src="/resources/images/logos/angular2/angular.png" height="40px" title="download Angular logo"></a>。
+makeTabs(
`webpack/ts/src/vendor.ts,

View File

@ -17,8 +17,7 @@ block includes
guides.
这份“快速起步”的目标是基于#{_Lang}构建并运行一个超级简单的Angular应用
并为文档其余部分的范例代码建立开发环境。
同时,它还可以作为构建真实应用的基础。
同时,它还会建立一个用于本指南中这些范例代码的公用开发环境。
.callout.is-helpful
header Don't want #{_Lang}?
@ -291,68 +290,104 @@ block install-packages
:marked
Create the file `app/app.module.ts` with the following content:
使用下列内容创建`app/app.module.ts`文件:
+makeExample('app/app.module.1.ts')(format='.')
:marked
This is the entry point to your application.
这里是应用的入口点。
Since the QuickStart application is a web application that runs in a browser, your root module
needs to import the
[`BrowserModule`](../latest/api/platform-browser/index/BrowserModule-class.html)
from `@angular/platform-browser` to the `imports` array.
由于QuickStart是一个运行在浏览器中的Web应用所以根模块需要从`@angular/platform-browser`中导入[`BrowserModule`](../latest/api/platform-browser/index/BrowserModule-class.html)并添加到`imports`数组中。
This is the smallest amount of Angular that is needed for a minimal application to run in the
browser.
这是要让一个最小的应用在浏览器中运行时对Angular的最低需求。
The QuickStart application doesn't do anything else, so you don't need any other modules. In a real
application, you'd likely import [`FormsModule`](../latest/api/forms/index/FormsModule-class
.html) as well as [`RouterModule`](../latest/api/router/index/RouterModule-class.html) and
[`HttpModule`](../latest/api/http/index/HttpModule-class.html). These are introduced in the
[Tour of Heroes Tutorial](../tutorial/).
QuickStart应用不做别的也就先不需要其他模块。在真实的应用中我们可能还得导入[`FormsModule`](../latest/api/forms/index/FormsModule-class
.html)、[`RouterModule`](../latest/api/router/index/RouterModule-class.html)和
[`HttpModule`](../latest/api/http/index/HttpModule-class.html)。这些会在[英雄指南教程](../tutorial/)中引入。
.l-main-section
h1#root-component Step !{step++}: Create a component and add it to your application
h1#root-component 步骤3创建组件并添加到应用中
:marked
Every Angular application has at least one component: the _root component_, named `AppComponent`
here.
每个Angular应用都至少有一个组件*根组件*,这里名叫`AppComponent`。
Components are the basic building blocks of Angular applications. A component controls a portion
of the screen&mdash;a *view*&mdash;through its associated template.
组件是Angualr应用的基本构造块。每个组件都会通过与它相关的模板来控制屏幕上的一小块视图
a#app-component
p.
#[b Create the component file]
#[code #[+adjExPath('app/app.component.ts')]] with the following content:
p.
#[b 使用下列内容创建组件文件]
#[code #[+adjExPath('app/app.component.ts')]]:
+makeExample('app/app.component.ts')
:marked
The QuickStart application has the same essential structure as any other Angular component:
QuickStart应用具有和其它Angular组件相同的基本结构
* **An import statement**. Importing gives your component access to
Angular's core [`@Component` decorator function](../latest/api/core/index/Component-decorator
.html).
* **一个import语句**。它让你能访问Angular核心库中的[`@Component`装饰器函数](../latest/api/core/index/Component-decorator.html)。
* **A @Component #{_decorator}** that associates *metadata* with the
`AppComponent` component class:
* **一个@Component#{_decoratorCn}**,它会把一份*元数据*关联到`AppComponent`组件类上:
- a *selector* that specifies a simple CSS selector for an HTML element that represents
the component.
- *selector*为用来代表该组件的HTML元素指定一个简单的CSS选择器。
- a *template* that tells Angular how to render the component's view.
- *template*用来告诉Angular如何渲染该组件的视图。
* **A component class** that controls the appearance and behavior of a view
* **组件类**通过它的模板来控制视图的外观和行为
through its template. Here, you only have the root component, `AppComponent`. Since you don't
need any application logic in the simple QuickStart example, it's empty.
这里,你只有一个根组件`AppComponent`。由于这个简单的QuickStart范例中并不需要应用逻辑因此它是空的。
You *export* the `AppComponent` class so that you can *import* it into the application that you
just created.
我们还要*导出*这个`AppComponent`类,以便让刚刚创建的这个应用导入它。
Edit the file `app/app.module.ts` to import your new `AppComponent` and add it in the
declarations and bootstrap fields in the `NgModule` decorator:
编辑`app/app.module.ts`文件,导入这个新的`AppComponent`,并把它添加到`NgModule`装饰器中的`declarations`和`bootstrap`字段:
+makeExample('app/app.module.ts', null, title='app/app.module.ts')
.l-main-section
h1#main Step !{step++}: Start up your application
h1#main 步骤4启动应用
block create-main
:marked
@ -373,14 +408,21 @@ block create-main
This code initializes the platform that your application runs in, then uses the platform to
bootstrap your `!{_AppModuleVsAppComp}`.
这些代码初始化了应用所在的平台,然后使用此平台引导你的`!{_AppModuleVsAppComp}`。
### Why create separate *<span ngio-ex>main.ts</span>*<span if-docs="ts">, app module</span> and app component files?
### 为什么要分别创建*<span ngio-ex>main.ts</span>*<span if-docs="ts">、应用模块</span>和应用组件的文件呢?
App bootstrapping is a separate concern from<span if-docs="ts"> creating a module or</span>
presenting a view. Testing the component is much easier if it doesn't also try to run the entire application.
应用的引导过程与<span if-docs="ts">创建模块或者</span>展现视图是相互独立的关注点。如果该组件不会试图运行整个应用,那么测试它就会更容易。
.callout.is-helpful
header Bootstrapping is platform-specific
header 引导过程是与平台有关的
:marked
Because the QuickStart application runs directly in the browser, `main.ts` imports the
@ -399,6 +441,7 @@ block create-main
.l-main-section
h1#index Step !{step++}: Define the web page that hosts the application
h1#index 步骤5定义该应用的宿主页面
:marked
In the *#{_indexHtmlDir}* folder,
create an `index.html` file and paste the following lines into it:
@ -412,22 +455,34 @@ h1#index Step !{step++}: Define the web page that hosts the application
:marked
The noteworthy sections here are:
这里值得注意的地方有:
* JavaScript libraries: `core-js` polyfills for older browsers, the `zone.js` and
`reflect-metadata` libraries needed by Angular, and the `SystemJS` library for module loading.
* JavaScript库`core-js`是为老式浏览器提供的填充库,`zone.js`和`reflect-metadata`库是Angular需要的而`SystemJS`库是用来做模块加载的。
* Configuration file for `SystemJS`, and a script
where you import and run the `app` module which refers to the `main` file that you just
wrote.
* `SystemJS`的配置文件和一段脚本,它导入并运行了我们刚刚在`main`文件中写的`app`模块。
* The [`<my-app>`](#my-app) tag in the `<body>` which is *where your app lives!*
* `<body>`中的[`<my-app>`](#my-app)标签是*应用程序生活的地方!*
:marked
## Add some style
## 添加一些样式
Styles aren't essential, but they're nice, and `index.html` assumes that you have
a stylesheet called `styles.css`.
样式不是必须的,但能让应用更漂亮。`index.html`中假定有一个叫做`styles.css`的样式表。
Create a `styles.css` file in the *#{_indexHtmlDir}* folder, and start styling,
perhaps with the minimal styles shown below.
在*#{_indexHtmlDir}*目录下创建一个`style.css`文件,并且用下面列出的最小化样式作为初始样式。
+makeExcerpt('styles.css (excerpt)', 'quickstart')
.callout.is-helpful
@ -452,11 +507,18 @@ aside.is-right
[Read more](https://github.com/angular/quickstart/blob/master/README.md#npm-scripts) about
other useful npm scripts included in this example's `package.json`.
到[这里](https://github.com/angular/quickstart/blob/master/README.md#npm-scripts)了解更多关于`package.json`中其它脚本的知识。
:marked
That command runs the following two parallel node processes:
该命令会同时运行两个并行的node进程
* The TypeScript compiler in watch mode.
* TypeScript编译器运行在监听模式。
* A static file server called _lite-server_ that loads `index.html` in a browser
and refreshes the browser when application files change.
* 一个名叫*lite-server*的静态文件服务器,它把`index.html`加载到浏览器中,并且在该应用中的文件发生变化时刷新浏览器。
In a few moments, a browser tab should open and display the following:
@ -473,19 +535,27 @@ block build-app
h1 Step !{step++}: Make some live changes
:marked
Try changing the message in `app/app.component.ts` to "My SECOND Angular 2 App".
尝试把`app/app.component.ts`中的消息修改成"My SECOND Angular 2 App"。
block server-watching
:marked
The TypeScript compiler and `lite-server` will detect your change, recompile the TypeScript into JavaScript,
refresh the browser, and display your revised message.
TypeScript编译器和`lite-server`将会检测这些修改重新把TypeScript编译成JavaScript刷新浏览器并显示修改过的消息。
Close the terminal window when you're done to terminate both the compiler and the server.
当终止了编译器和服务器之后可以关闭terminal窗口。
.l-main-section
h1#wrap-up Wrap up and next steps
h1#wrap-up 收工,下一步
:marked
The final project folder structure looks like this:
项目的最终目录结构看起来是这样的:
block project-file-structure
.filetree
.file angular2-quickstart
@ -506,20 +576,34 @@ block project-file-structure
:marked
To see the file contents, open the <live-example></live-example>.
要查看文件的内容,请打开<live-example></live-example>。
.l-main-section
:marked
## What next?
## 下一步干什么?
This first application doesn't do much. It's basically "Hello, World" for Angular 2.
第一个应用没做什么它只是一个Angular 2的"Hello, World"而已。
You wrote a little Angular component, created a simple `index.html`, and launched with a
static file server.
我们写了一个很小的Angular组件递减了一个简单的`index.html`,并且启动了一个静态文件服务器。
+ifDocsFor('ts')
:marked
You also created the basic application setup that you'll re-use for other
sections in this guide. From here, the changes you'll make in the
`package.json` or `index.html` files are only minor updates to add libraries or some css
stylesheets. You also won't need to revisit module loading again.
我们还设置了一个基本的应用环境,你可以把它用在本指南的其它部分。以后,我们对`package.json`和`index.html`的修改将仅限于添加库或一些css样式不用再需要修改模块加载部分。
:marked
To take the next step and build a small application that demonstrates real features that you can
build with Angular, carry on to the [Tour of Heroes tutorial](./tutorial)!
下一步我们会开始构建一个小型的应用用于示范能通过Angular构建的真实特性。
来吧!开始[“英雄指南”教程](./tutorial)

View File

@ -1108,6 +1108,8 @@ block extract-id
:marked
Delete the `<h1>` at the top (forgot about it during the `AppComponent`-to-`HeroesComponent` conversion).
删除顶部的`<h1>`(在从`AppComponent`转到`HeroesComponent`期间可以先忘掉它)。
Delete the last line of the template with the `<my-hero-detail>` tags.
删除模板最后带有`<my-hero-detail>`标签的那一行。

View File

@ -72,7 +72,7 @@ block http-library
It's Angular's optional approach to web access and it exists as a separate add-on module called `@angular/http`,
shipped in a separate script file as part of the Angular npm package.
`Http`***并不是***Angular的核心模块。
`HttpModule`***并不是***Angular的核心模块。
它是Angular用来进行Web访问的一种可选方式并通过Angular包中一个名叫`@angular/http`的独立附属模块发布了出来。
Fortunately we're ready to import from `@angular/http` because `systemjs.config` configured *SystemJS* to load that library when we need it.
@ -291,7 +291,7 @@ block get-heroes-details
仔细看看这个由服务器返回的数据的形态。
这个*内存Web API*的范例中所做的是返回一个带有`data`属性的对象。
你的API也可以返回其它东西。
你的API也可以返回其它东西。请调整这些代码以匹配*你的Web API*。
:marked
The caller is unaware of these machinations. It receives a !{_Promise} of *heroes* just as it did before.
@ -357,9 +357,15 @@ block get-heroes-details
:marked
## Update hero details
## 更新英雄详情
We can edit a hero's name already in the hero detail view. Go ahead and try
it. As we type, the hero name is updated in the view heading.
But when we hit the `Back` button, the changes are lost!
我们已经可以在英雄详情中编辑英雄的名字了。来试试吧。在输入的时候,页头上的英雄名字也会随之更新。
不过当我们点了后退按钮时,这些更新就丢失了。
.l-sub-section
:marked
Updates weren't lost before, what's happening?
@ -368,28 +374,42 @@ block get-heroes-details
from a server, if we want changes to persist, we'll need to write them back to
the server.
以前是不会丢失更新的,现在是怎么回事?
当该应用使用mock出来的英雄列表时修改的是一份全局共享的英雄列表而现在改成了从服务器获取数据。
如果我们希望这些更改被持久化,我们就得把它们写回服务器。
:marked
### Save hero details
### 保存英雄详情
Let's ensure that edits to a hero's name aren't lost. Start by adding,
to the end of the hero detail template, a save button with a `click` event
binding that invokes a new component method named `save`:
我们先来确保对英雄名字的编辑不会丢失。先在英雄详情模板的底部添加一个“保存”按钮,它绑定了一个`click`事件,事件中调用组件中一个名叫`save`的新方法:
+makeExcerpt('app/hero-detail.component.html', 'save')
:marked
The `save` method persists hero name changes using the hero service
`update` method and then navigates back to the previous view:
`save`方法使用hero服务的`update`方法来持久化对英雄名字的修改,然后导航回前一个页面:
+makeExcerpt('app/hero-detail.component.ts', 'save')
:marked
### Hero service `update` method
### hero服务的`update`方法
The overall structure of the `update` method is similar to that of
`getHeroes`, although we'll use an HTTP _put_ to persist changes
server-side:
`update`方法的大致结构与`getHeroes`类似不过我们使用HTTP的*put*方法来把修改持久化到服务端:
+makeExcerpt('app/hero.service.ts', 'update')
:marked
@ -398,51 +418,80 @@ block get-heroes-details
calling `!{_JSON_stringify}`. We identify the body content type
(`application/json`) in the request header.
我们通过一个编码在URL中的英雄id来告诉服务器应该更新哪个英雄。put的body是该英雄的JSON字符串它是通过调用`!{_JSON_stringify}`得到的。
并且在请求头中标记出的body的内容类型`application/json`)。
Refresh the browser and give it a try. Changes to hero names should now persist.
刷新浏览器试一下,对英雄名字的修改确实已经被持久化了。
.l-main-section
:marked
## Add a hero
## 添加英雄
To add a new hero we need to know the hero's name. Let's use an input
element for that, paired with an add button.
要添加一个新的英雄我们得先知道英雄的名字。我们使用一个input元素和一个“add”按钮来拿到它。
Insert the following into the heroes component HTML, first thing after
the heading:
把下列代码插入heroes组件的HTML中放在紧挨着头部的地方
+makeExcerpt('app/heroes.component.html', 'add')
:marked
In response to a click event, we call the component's click handler and then
clear the input field so that it will be ready to use for another name.
在对click事件的响应中我们要调用组建的click处理器然后清空这个输入框以便用来输入另一个名字。
+makeExcerpt('app/heroes.component.ts', 'add')
:marked
When the given name is non-blank, the handler delegates creation of the
named hero to the hero service, and then adds the new hero to our !{_array}.
当指定的名字不为空的时候click处理器就会委托hero服务来创建一个具有此名字的英雄并把这个新的英雄添加到我们的数组中。
Finally, we implement the `create` method in the `HeroService` class.
最后,我们在`HeroService`类中实现这个`create`方法。
+makeExcerpt('app/hero.service.ts', 'create')
:marked
Refresh the browser and create some new heroes!
刷新浏览器,并创建一些新的英雄!
.l-main-section
:marked
## Delete a hero
## 删除一个英雄
Too many heroes?
Let's add a delete button to each hero in the heroes view.
英雄太多了?
我们在英雄列表视图中来为每个英雄添加一个删除按钮吧。
Add this button element to the heroes component HTML, right after the hero
name in the repeated `<li>` tag:
把这个button元素添加到英雄列表组件的HTML中把它放在`<li>`标签中的英雄名紧后边:
+makeExcerpt('app/heroes.component.html', 'delete', '')
:marked
The `<li>` element should now look like this:
`<li>`元素应该变成了这样:
+makeExcerpt('app/heroes.component.html', 'li-element')
:marked
@ -451,8 +500,12 @@ block get-heroes-details
don't want the `<li>` click handler to be triggered because that would
select the hero that we are going to delete!
除了调用组件的`delete`方法之外,这个`delete`按钮的click处理器还应该阻止click事件向上冒泡 —— 我们并不希望触发`<li>`的事件处理器,否则它会选中我们要删除的这位英雄。
The logic of the `delete` handler is a bit trickier:
`delete`处理器的逻辑略复杂:
+makeExcerpt('app/heroes.component.ts', 'delete')
:marked
@ -460,22 +513,33 @@ block get-heroes-details
is still responsible for updating the display: it removes the deleted hero
from the !{_array} and resets the selected hero if necessary.
当然我们仍然把删除英雄的操作委托给了hero服务不过该组件仍然正确的更新了显示它从数组中移除了被删除的英雄如果删除的是正选中的英雄还会清空选择。
:marked
We want our delete button to be placed at the far right of the hero entry.
This extra CSS accomplishes that:
我们希望删除按钮被放在英雄条目的最右边。
于是CSS变成了这样
+makeExcerpt('app/heroes.component.css', 'additions')
:marked
### Hero service `delete` method
### hero服务的`delete`方法
The hero service's `delete` method uses the _delete_ HTTP method to remove the hero from the server:
hero服务的`delete`方法使用HTTP的*delete*方法来从服务器上移除该英雄:
+makeExcerpt('app/hero.service.ts', 'delete')
:marked
Refresh the browser and try the new delete functionality.
刷新浏览器,并试一下这个新的删除功能。
:marked
## !{_Observable}s
@ -485,7 +549,7 @@ block observables-section-intro
:marked
Each `Http` service method returns an `Observable` of HTTP `Response` objects.
`Http`服务中的每个方法都返回一个Http `Response`对象的`Observable`实例。
`Http`服务中的每个方法都返回一个HTTP `Response`对象的`Observable`实例。
Our `HeroService` converts that `Observable` into a `Promise` and returns the promise to the caller.
In this section we learn to return the `Observable` directly and discuss when and why that might be
@ -520,7 +584,7 @@ block observables-section-intro
A single result in the form of a promise is easy for the calling component to consume
and it helps that promises are widely understood by JavaScript programmers.
转换成承诺通常是更好地选择,我们通常要求`http`获取单块数据。只要接收到数据,就算完成。
转换成承诺通常是更好地选择,我们通常要求`http.get`获取单块数据。只要接收到数据,就算完成。
使用承诺这种形式的结果是让调用方更容易写并且承诺已经在JavaScript程序员中被广泛接受了。
:marked
But requests aren't always "one and done". We may start one request,
@ -698,7 +762,7 @@ block observable-transformers
until the service supports that feature, a topic for another day.
We are content for now to discard unwanted results.
注意_取消_`HeroSearchService`的可观察对象并不会实际中止abort一个未完成的http请求,除非有一天我们支持了这个特性,这个问题我们以后再讨论。
注意_取消_`HeroSearchService`的可观察对象并不会实际中止abort一个未完成的HTTP请求,除非有一天我们支持了这个特性,这个问题我们以后再讨论。
目前我们的做法只是丢弃不希望的结果。
:marked
@ -741,7 +805,7 @@ block observable-transformers
:marked
We load them all at once by importing `rxjs-extensions` at the top of `AppModule`.
我们在`AppModule`中导入`rxjs-extensions`就可以一次性加载它们。
我们在顶级的`AppModule`中导入`rxjs-extensions`就可以一次性加载它们。
+makeExcerpt('app/app.module.ts', 'rxjs-extensions')(format='.')
@ -763,7 +827,7 @@ block observable-transformers
<span ngio-ex>hero-search.component.ts</span>
and add it to the `!{_declarations}` !{_array}:
最后,从`'./hero-search.component.ts'` 导入`HeroSearchComponent`并将其添加到`declarations`数组中。
最后,从<span ngio-ex>hero-search.component.ts</span>中导入`HeroSearchComponent`并将其添加到`declarations`数组中。
+makeExcerpt(declFile, 'search')