parent
67052ac925
commit
2a1c3626c5
|
@ -975,7 +975,7 @@ a(id="controllers-components")
|
|||
In both Angular 1 and Angular 2, we use Angular modules to
|
||||
help us organize our application into cohesive blocks of functionality.
|
||||
|
||||
无论在Angular 1还是Angular 2中,我们都要借助“模块”来把应用拆分成一些内聚的功能块儿。
|
||||
无论在Angular 1还是Angular 2中,我们都要借助“模块”来把应用拆分成一些紧密相关的功能块。
|
||||
|
||||
In Angular 1, we write the code that provides the model and the methods for the view in a **controller**.
|
||||
In Angular 2, we build a **component**.
|
||||
|
|
|
@ -364,11 +364,11 @@ a(id="countdown-tests")
|
|||
|
||||
Then Angular calls the `ngAfterViewInit` lifecycle hook at which time it is *too late* to update the parent view's display of the countdown seconds. Angular's unidirectional data flow rule prevents us from updating the parent view's in the same cycle. We have to *wait one turn* before we can display the seconds.
|
||||
|
||||
然后Angular会调用`ngAfterViewInit`生命周期钩子,但这时候再更新父组件视图的倒计时就已经太晚了。Angular的单向数据流规则会阻止在同一个周期内更新父组件视图。我们在显示秒数之前会被迫*再等一轮儿*。
|
||||
然后Angular会调用`ngAfterViewInit`生命周期钩子,但这时候再更新父组件视图的倒计时就已经太晚了。Angular的单向数据流规则会阻止在同一个周期内更新父组件视图。我们在显示秒数之前会被迫*再等一轮*。
|
||||
|
||||
We use `setTimeout` to wait one tick and then revise the `seconds` method so that it takes future values from the timer component.
|
||||
|
||||
使用`setTimeout`来等下一轮儿,然后改写`seconds`方法,这样它接下来就会从注入的这个计时器组件里获取秒数的值。
|
||||
使用`setTimeout`来等下一轮,然后改写`seconds`方法,这样它接下来就会从注入的这个计时器组件里获取秒数的值。
|
||||
|
||||
### Test it
|
||||
### 测试
|
||||
|
|
|
@ -635,7 +635,7 @@ figure.image-display
|
|||
If it doesn't, it may be able to make one with the help of a ***provider***.
|
||||
A *provider* is a recipe for delivering a service associated with a *token*.
|
||||
|
||||
注入器从哪儿得到的依赖?
|
||||
注入器从哪得到的依赖?
|
||||
它可能在自己内部容器里已经有该依赖了。
|
||||
如果它没有,也能在***提供商***的帮助下新建一个。
|
||||
*提供商*就是一个用于交付服务的配方,它被关联到一个令牌。
|
||||
|
|
|
@ -207,7 +207,7 @@ block includes
|
|||
The practice of writing compound words or phrases such that each word or abbreviation begins with a capital letter
|
||||
_except the first letter which is a lowercase letter_.
|
||||
|
||||
驼峰式命名法是指除了首字母要小写外,每个单词或缩写都以大写字母开头儿的形式来书写复合词或短语的一种实践。
|
||||
驼峰式命名法是指除了首字母要小写外,每个单词或缩写都以大写字母开头的形式来书写复合词或短语的一种实践。
|
||||
|
||||
Function, property, and method names are typically spelled in camelCase. Examples include: `square`, `firstName` and `getHeroes`.
|
||||
|
||||
|
@ -233,7 +233,7 @@ block includes
|
|||
The Component is one of the most important building blocks in the Angular system.
|
||||
It is, in fact, an Angular [Directive](#directive) with a companion [Template](#template).
|
||||
|
||||
组件是Angular系统中最重要的基本构造块儿之一。
|
||||
组件是Angular系统中最重要的基本构造块之一。
|
||||
它其实是一个拥有[模板(Template)](#template)的[指令(Directive)](#directive)。
|
||||
|
||||
The developer applies the `#{_at}Component` !{_decoratorLink} to
|
||||
|
@ -976,7 +976,7 @@ a#Q
|
|||
is that the package name begins with the Angular *scope name*, `@angular`.
|
||||
|
||||
使用和导入*普通*包相同的方式导入范围化包。
|
||||
从消费者的视角看,唯一的不同是那些包的名字是用Angular的*范围名*`@angular`开头儿的。
|
||||
从消费者的视角看,唯一的不同是那些包的名字是用Angular的*范围名*`@angular`开头的。
|
||||
|
||||
+makeExcerpt('architecture/ts/app/app.component.ts', 'import', '')
|
||||
|
||||
|
@ -1050,7 +1050,7 @@ a#snake-case
|
|||
the support and continuing guidance of an Angular [Directive](#directive),
|
||||
most notably a [Component](#component).
|
||||
|
||||
模板是一大块儿HTML。Angular会在[指令(Directive)](#directive)特别是[组件(Component)](#component)的支持和持续指导下,用它来渲染[视图(View)](#view)。
|
||||
模板是一大块HTML。Angular会在[指令(Directive)](#directive)特别是[组件(Component)](#component)的支持和持续指导下,用它来渲染[视图(View)](#view)。
|
||||
|
||||
We write templates in a special [Template Syntax](/docs/ts/latest/guide/template-syntax.html).
|
||||
|
||||
|
@ -1164,7 +1164,7 @@ a#U
|
|||
A view is a portion of the screen that displays information and responds
|
||||
to user actions such as clicks, mouse moves, and keystrokes.
|
||||
|
||||
视图是屏幕中一小块儿,用来显示信息并回应用户动作,比如点击、移动鼠标和按键等。
|
||||
视图是屏幕中一小块,用来显示信息并回应用户动作,比如点击、移动鼠标和按键等。
|
||||
|
||||
Angular renders a view under the control of one or more [Directives](#directive),
|
||||
especially [Component](#component) directives and their companion [Templates](#template).
|
||||
|
|
|
@ -356,7 +356,7 @@ figure
|
|||
A template looks like regular HTML, except for a few differences. Here is a
|
||||
template for our `HeroListComponent`:
|
||||
|
||||
多数情况下,模板看起来很像标准HTML……当然也有一小点儿奇怪的地方。下面是`HeroListComponent`组件的一个模板。
|
||||
多数情况下,模板看起来很像标准HTML……当然也有一点奇怪的地方。下面是`HeroListComponent`组件的一个模板。
|
||||
|
||||
+makeExample('app/hero-list.component.html')
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ block highlight-directive-1
|
|||
|
||||
We need a prefix of our own, preferably short, and `my` will do for now.
|
||||
|
||||
我们需要一个自己的前缀,最好短点儿,目前用的这个`my`前缀就不错。
|
||||
我们需要一个自己的前缀,最好短点,目前用的这个`my`前缀就不错。
|
||||
p
|
||||
| After the #[code @Directive] metadata comes the directive's controller class, which contains the logic for the directive.
|
||||
+ifDocsFor('ts')
|
||||
|
@ -193,7 +193,7 @@ a#apply-directive
|
|||
applies the directive as an attribute to a paragraph (`p`) element.
|
||||
In Angular terms, the `<p>` element will be the attribute **host**.
|
||||
|
||||
这个例子中,`AppComponent`是用来测试`HighlightDirective`的一个壳儿。
|
||||
这个例子中,`AppComponent`是用来测试`HighlightDirective`的一个壳。
|
||||
我们来给它一个新的模板,把这个指令作为属性应用到一个段落(`p`)元素上。
|
||||
用Angular的话说,`<p>`元素就是这个属性型指令的**宿主**。
|
||||
p
|
||||
|
@ -458,7 +458,7 @@ a#input
|
|||
And yet this code works. Where is the template `color` value going?
|
||||
|
||||
**但我们从来没有在宿主`AppComponent`上定义过color属性**!
|
||||
不过这段代码却能正常工作。模板中的`color`值哪儿去了?
|
||||
不过这段代码却能正常工作。模板中的`color`值哪去了?
|
||||
|
||||
Browser debugging reveals that Angular dynamically added a `color` property
|
||||
to the runtime instance of the `AppComponent`.
|
||||
|
|
|
@ -262,7 +262,7 @@ block style-url
|
|||
component file.
|
||||
|
||||
URL是***相对于应用程序根目录的***,它通常是应用的宿主页面`index.html`所在的地方。
|
||||
这个样式文件的URL*不是*相对于组件文件的。这就是为什么范例中的URL用`app/`开头儿。
|
||||
这个样式文件的URL*不是*相对于组件文件的。这就是为什么范例中的URL用`app/`开头。
|
||||
参见[附录2](#relative-urls)来了解如何指定相对于组件文件的URL。
|
||||
|
||||
block module-bundlers
|
||||
|
@ -444,7 +444,7 @@ code-example(format="").
|
|||
|
||||
We'll likely live with *emulated* mode until shadow DOM gains traction.
|
||||
|
||||
小伙伴儿们会很愉快的使用*仿真*模式 —— 直到有一天Shadow DOM获得全面支持。
|
||||
小伙伴们会很愉快的使用*仿真*模式 —— 直到有一天Shadow DOM获得全面支持。
|
||||
|
||||
a#relative-urls
|
||||
.l-main-section
|
||||
|
|
|
@ -1077,7 +1077,7 @@ block dart-diff-const-metadata-ctor
|
|||
|
||||
注意,我们在#{anexportedvarCn}中捕获了这个工厂提供商:`heroServiceProvider`。
|
||||
这个额外的步骤让工厂提供商可被复用。
|
||||
只要需要,我们就可以使用这个#{variableCn}注册`HeroService`,无论在哪儿。
|
||||
只要需要,我们就可以使用这个#{variableCn}注册`HeroService`,无论在哪。
|
||||
|
||||
In our sample, we need it only in the `HeroesComponent`,
|
||||
where it replaces the previous `HeroService` registration in the metadata `providers` #{_array}.
|
||||
|
|
|
@ -231,7 +231,7 @@ figure.image-display
|
|||
That's the Angular "repeater" directive.
|
||||
Its presence on the `<li>` tag marks that `<li>` element (and its children) as the "repeater template".
|
||||
|
||||
我们把看起来有点儿神秘的`*ngFor`加到`<li>`元素上。
|
||||
我们把看起来有点神秘的`*ngFor`加到`<li>`元素上。
|
||||
这就是Angular的“重复器”指令。
|
||||
它出现在`<li>`标签上就表示把`<li>`及其子元素作为“重复器的模板”。
|
||||
.alert.is-important
|
||||
|
|
|
@ -103,7 +103,7 @@ figure.image-display
|
|||
|
||||
Two of the three fields on this form are required. Required fields have a green bar on the left to make them easy to spot.
|
||||
|
||||
这个表单中的三个字段都是必填的。这些必填的字段在左侧会有一个绿色的条儿,让它们更容易看出来。
|
||||
这个表单中的三个字段都是必填的。这些必填的字段在左侧会有一个绿色的竖条,让它们更容易看出来。
|
||||
|
||||
If we delete the hero name, the form displays a validation error in an attention grabbing style:
|
||||
|
||||
|
@ -421,7 +421,7 @@ code-example(format="").
|
|||
|
||||
`container`、`form-group`、`form-control`和`btn`类来自[Twitter Bootstrap](http://getbootstrap.com/css/)。纯粹是装饰。
|
||||
我们使用Bootstrap来打扮我们的表单。
|
||||
嘿,一点儿样式儿都没有的表单算个啥!
|
||||
嘿,一点样式都没有的表单算个啥!
|
||||
|
||||
.callout.is-important
|
||||
header Angular Forms Do Not Require A Style Library
|
||||
|
@ -807,7 +807,7 @@ figure.image-display
|
|||
strong visual signal when the data are invalid and we want to mark required fields.
|
||||
So we add custom CSS for visual feedback.
|
||||
|
||||
(`ng-valid` | `ng-invalid`)这一对儿是我们最感兴趣的。当数据变得无效时,我们希望发出一个强力的视觉信号。我们还希望标记出必填字段。
|
||||
(`ng-valid` | `ng-invalid`)这一对是我们最感兴趣的。当数据变得无效时,我们希望发出一个强力的视觉信号。我们还希望标记出必填字段。
|
||||
于是我们加入自定义CSS来提供视觉反馈。
|
||||
|
||||
**Delete** the `#spy` template reference variable and `TODO` as they have served their purpose.
|
||||
|
@ -1099,7 +1099,7 @@ figure.image-display
|
|||
Later in the template we bind the button's `disabled` property to the form's over-all validity via
|
||||
the `heroForm` variable. Here's that bit of markup:
|
||||
|
||||
模板中稍后的部分,通过`heroForm`变量,我们把按钮的`disabled`属性绑定到了表单的全员有效性。这里是那点儿HTML:
|
||||
模板中稍后的部分,通过`heroForm`变量,我们把按钮的`disabled`属性绑定到了表单的全员有效性。这里是那点HTML:
|
||||
|
||||
+makeExample('forms/ts/app/hero-form.component.html', 'submit-button')
|
||||
:marked
|
||||
|
@ -1186,7 +1186,7 @@ figure.image-display
|
|||
Add the following block of HTML below the `<div>` wrapper we just wrote:
|
||||
|
||||
现在,当表单处于已提交状态时,我们需要显示一些别的东西。
|
||||
在我们刚刚写的`<div>`包装下方,添加下列HTML块儿:
|
||||
在我们刚刚写的`<div>`包装下方,添加下列HTML块:
|
||||
|
||||
+makeExample('forms/ts/app/hero-form.component.html', 'submitted', 'app/hero-form.component.html (节选)')
|
||||
|
||||
|
@ -1195,7 +1195,7 @@ figure.image-display
|
|||
This slug of HTML only appears while the component is in the submitted state.
|
||||
|
||||
我们的英雄又来了,它通过插值表达式绑定显示为只读内容。
|
||||
这一小段儿HTML只在组件处于已提交状态时才会显示。
|
||||
这一小段HTML只在组件处于已提交状态时才会显示。
|
||||
|
||||
We added an Edit button whose click event is bound to an expression
|
||||
that clears the `submitted` flag.
|
||||
|
@ -1204,11 +1204,11 @@ figure.image-display
|
|||
|
||||
When we click it, this block disappears and the editable form reappears.
|
||||
|
||||
当我们点它时,这个只读块儿消失了,可编辑的表单重新出现了。
|
||||
当我们点它时,这个只读块消失了,可编辑的表单重新出现了。
|
||||
|
||||
That's as much drama as we can muster for now.
|
||||
|
||||
现在,它比我们那个刚好够用的版本好玩儿多了。
|
||||
现在,它比我们那个刚好够用的版本好玩多了。
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
|
|
|
@ -38,7 +38,7 @@ block includes
|
|||
We oversimplified. In fact, there is no such thing as ***the*** injector!
|
||||
An application may have multiple injectors!
|
||||
|
||||
我们其实有点简化过度了。实际上,没有***那个(唯一的)***注入器这回事儿,因为一个应用中可能有很多注入器。
|
||||
我们其实有点简化过度了。实际上,没有***那个(唯一的)***注入器这回事,因为一个应用中可能有很多注入器。
|
||||
|
||||
An Angular application is a tree of components. Each component instance has its own injector!
|
||||
The tree of components parallels the tree of injectors.
|
||||
|
@ -211,7 +211,7 @@ figure.image-display
|
|||
:marked
|
||||
Now here it’s getting interesting. The `HeroEditorComponent`defines a template with an input to change the name of the hero and a `cancel` and a `save` button. Remember that we said we want to have the flexibility to cancel our editing and restore the old value? This means we need to maintain two copies of our `Hero` that we want to edit. Thinking ahead, this is a perfect use case to abstract it into its own generic service since we have probably more cases like this in our app.
|
||||
|
||||
现在,事情开始变得有趣儿了。`HeroEditorComponent`定义了一个模板,它有一个输入框来修改英雄的名字,以及一个`cancel`按钮和一个`save`按钮。
|
||||
现在,事情开始变得有趣了。`HeroEditorComponent`定义了一个模板,它有一个输入框来修改英雄的名字,以及一个`cancel`按钮和一个`save`按钮。
|
||||
还记得吗?我们说过要能够灵活的取消编辑,并且回复原值吗?这意味着我们得维护这个待编辑`Hero`的两份实例。
|
||||
想得超前一点,这是一个把它抽象成一个通用服务的完美案例,因为将来我们的应用中可能会需要更多与此类似的操作逻辑。
|
||||
|
||||
|
@ -245,7 +245,7 @@ figure.image-display
|
|||
Couldn’t we simply alter our !{_root_NgModule} to include this provider?
|
||||
|
||||
它往`HeroEditComponent`的注入器中添加了一个`RestoreService`提供商。
|
||||
不能简化点儿,直接在我们的!{_root_NgModule}后面包含这个提供商吗?
|
||||
不能简化点,直接在我们的!{_root_NgModule}后面包含这个提供商吗?
|
||||
|
||||
+makeExcerpt(_appModuleTsVsMainTs, 'bad-alternative')
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ block includes
|
|||
:marked
|
||||
**Angular Modules** help organize an application into cohesive blocks of functionality.
|
||||
|
||||
**Angular模块**能帮你把应用组织成多个内聚的功能块儿。
|
||||
**Angular模块**能帮你把应用组织成多个内聚的功能块。
|
||||
|
||||
An Angular Module is a _class_ adorned with the **@NgModule** decorator function.
|
||||
`@NgModule` takes a metadata object that tells Angular how to compile and run module code.
|
||||
|
@ -124,7 +124,7 @@ a#angular-modularity
|
|||
cohesive blocks of functionality, each focused on a
|
||||
feature area, application business domain, workflow, or common collection of utilities.
|
||||
|
||||
Angular模块把组件、指令和管道打包成内聚的功能块儿,每一个都聚焦于一个特性分区、业务领域、工作流,或一组通用的工具。
|
||||
Angular模块把组件、指令和管道打包成内聚的功能块,每一个都聚焦于一个特性分区、业务领域、工作流,或一组通用的工具。
|
||||
|
||||
Modules can also add services to the application.
|
||||
Such services might be internally-developed such as the application logger.
|
||||
|
|
|
@ -593,14 +593,14 @@ h3#async-pipe 非纯管道#[i AsyncPipe]
|
|||
不管我们怎么做,估计它都会是一个可怕的主意。
|
||||
但即便如此,为了讲解这个技术点,我们还是写一个吧。
|
||||
时刻记住,非纯管道可能每隔几微秒就会被调用一次。
|
||||
如果我们不小心点儿,这个管道就会发起一大堆请求“攻击”服务器。
|
||||
如果我们不小心点,这个管道就会发起一大堆请求“攻击”服务器。
|
||||
|
||||
We are careful. Our pipe only makes a server call if the request URL has changed.
|
||||
It caches the request URL and waits for a result which it also caches when it arrives.
|
||||
The pipe returns the cached result (which is null while a request is in flight)
|
||||
after every Angular call and only contacts the server as necessary.
|
||||
|
||||
我们确实得小心点儿。所以这个管道只有当所请求的URL发生变化时才会向服务器发起请求。
|
||||
我们确实得小心点。所以这个管道只有当所请求的URL发生变化时才会向服务器发起请求。
|
||||
它会缓存这个请求的URL,并等待一个结果,当结果发回来时,就缓存它。
|
||||
以后每当Angular调用此管道时,它都会返回这个缓存的结果(当请求尚未返回时,此结果是空),只在必要时才会去联系服务器。
|
||||
|
||||
|
|
|
@ -796,7 +796,7 @@ a#base-href
|
|||
It's not part of the Angular 2 core. The router is an optional service because not all applications
|
||||
need routing and, depending on your requirements, you may need a different routing library.
|
||||
|
||||
组件路由器在它自己的`@angular/router`包儿中。
|
||||
组件路由器在它自己的`@angular/router`包中。
|
||||
它不是Angular 2内核的一部分。该路由器是可选的服务,这是因为并不是所有应用都需要路由,并且,如果需要,你还可能需要另外的路由库。
|
||||
|
||||
We teach our router how to navigate by configuring it with routes.
|
||||
|
|
|
@ -690,7 +690,7 @@ code-example(format="." language="javascript").
|
|||
:marked
|
||||
We may be able to skip the `JSON.stringify` step in the near future.
|
||||
|
||||
用不了多久,我们就能跳过`JSON.stringify`这一步儿了。
|
||||
用不了多久,我们就能跳过`JSON.stringify`这一步了。
|
||||
|
||||
:marked
|
||||
### JSON results
|
||||
|
|
|
@ -83,7 +83,7 @@ block includes
|
|||
directive: it takes a boolean and makes an entire chunk of DOM appear
|
||||
or disappear.
|
||||
|
||||
我们重点看下`ngIf`。它是一个很好的结构型指令案例:它接受一个布尔值,并据此让一整块儿DOM树出现或消失。
|
||||
我们重点看下`ngIf`。它是一个很好的结构型指令案例:它接受一个布尔值,并据此让一整块DOM树出现或消失。
|
||||
|
||||
+makeExample('structural-directives/ts/app/structural-directives.component.html', 'ngIf')(format=".")
|
||||
|
||||
|
|
|
@ -1528,7 +1528,7 @@ block style-property-name-dart-diff
|
|||
|
||||
Let's try something silly like forcing the input value to uppercase:
|
||||
|
||||
来做点淘气的事儿吧,比如强制让输入值变成大写形式:
|
||||
来做点淘气的事吧,比如强制让输入值变成大写形式:
|
||||
+makeExample('template-syntax/ts/app/app.component.html', 'NgModel-4')(format=".")
|
||||
:marked
|
||||
Here are all variations in action, including the uppercase version:
|
||||
|
@ -1792,8 +1792,8 @@ block dart-no-truthy-falsey
|
|||
Our goal is to present a list of items. We define a block of HTML that defines how a single item should be displayed.
|
||||
We tell Angular to use that block as a template for rendering each item in the list.
|
||||
|
||||
我们的目标是展示一个由多个条目组成的列表。我们定义了一个HTML块儿,它规定了单个条目应该如何显示。
|
||||
我们告诉Angular把这个块儿当做模板,渲染列表中的每个条目。
|
||||
我们的目标是展示一个由多个条目组成的列表。我们定义了一个HTML块,它规定了单个条目应该如何显示。
|
||||
我们告诉Angular把这个块当做模板,渲染列表中的每个条目。
|
||||
|
||||
Here is an example of `NgFor` applied to a simple `<div>`:
|
||||
|
||||
|
@ -1851,7 +1851,7 @@ block dart-no-truthy-falsey
|
|||
:marked
|
||||
A template input variable is **not** the same as a [template reference variable](#ref-vars)!
|
||||
|
||||
模板输入变量和[模板引用变量](#ref-vars)**不是**一回事儿!
|
||||
模板输入变量和[模板引用变量](#ref-vars)**不是**一回事!
|
||||
|
||||
:marked
|
||||
We use this variable within the template to access a hero’s properties,
|
||||
|
@ -1958,7 +1958,7 @@ figure.image-display
|
|||
In this section we go under the hood and see how
|
||||
Angular strips away the `*` and expands the HTML into the `<template>` tags for us.
|
||||
|
||||
在这一节,我们将掀开引擎盖儿,看看Angular是怎样替我们扒掉这个`*`,并且把这段HTML展开到`<template>`标签中的。
|
||||
在这一节,我们将掀开引擎盖,看看Angular是怎样替我们扒掉这个`*`,并且把这段HTML展开到`<template>`标签中的。
|
||||
|
||||
:marked
|
||||
### Expanding `*ngIf`
|
||||
|
@ -2130,7 +2130,7 @@ figure.image-display
|
|||
A template reference variable, `theForm`, appears three times in this example, separated
|
||||
by a large amount of HTML.
|
||||
|
||||
模板引用变量`theForm`在这个例子中出现了三次,中间隔着一大段儿HTML。
|
||||
模板引用变量`theForm`在这个例子中出现了三次,中间隔着一大段HTML。
|
||||
+makeExample('template-syntax/ts/app/app.component.html', 'ref-form-a')(format=".")
|
||||
:marked
|
||||
What is the value of `theForm`?
|
||||
|
|
|
@ -63,7 +63,7 @@ a(id="top")
|
|||
|
||||
- where to put the test file
|
||||
|
||||
- 测试文件存放到哪儿
|
||||
- 测试文件存放到哪
|
||||
|
||||
- load a test file with systemJS
|
||||
|
||||
|
|
|
@ -1520,7 +1520,7 @@ code-example(format="").
|
|||
|
||||
我们已经完成了准备工作,接下来就开始把PhoneCat升级到Angular 2。
|
||||
我们将在Angular 2[升级模块](#upgrading-with-the-upgrade-adapter)的帮助下增量式的完成此项工作。
|
||||
等我们完成的那一刻,就能把Angular 1从项目中完全移除了,但其中的关键是在不破坏此程序的前提下一小块儿一小块儿的完成它。
|
||||
等我们完成的那一刻,就能把Angular 1从项目中完全移除了,但其中的关键是在不破坏此程序的前提下一小块一小块的完成它。
|
||||
|
||||
.alert.is-important
|
||||
:marked
|
||||
|
@ -1611,7 +1611,7 @@ code-example(format="").
|
|||
we can start converting the individual pieces to Angular 2.
|
||||
|
||||
接下来,我们把该应用程序引导改装为一个同时支持Angular 1和Angular 2的*混合式应用*。
|
||||
然后,就能开始把这些不可分割的小块儿转换到Angular 2了。
|
||||
然后,就能开始把这些不可分割的小块转换到Angular 2了。
|
||||
|
||||
To bootstrap a hybrid application, we first need to initialize an `UpgradeAdapter`,
|
||||
which [provides the glue](#upgrading-with-the-upgrade-adapter) that joins the two
|
||||
|
@ -1668,7 +1668,7 @@ code-example(format="").
|
|||
to load phone information from the server. Right now it's implemented with
|
||||
ngResource and we're using it for two things:
|
||||
|
||||
我们要移植到Angular 2的第一块儿是`Phone`工厂(位于`app/js/core/phones.factory.ts`),
|
||||
我们要移植到Angular 2的第一块是`Phone`工厂(位于`app/js/core/phones.factory.ts`),
|
||||
并且让它能帮助控制器从服务器上加载电话信息。目前,它是用`ngResource`实现的,我们用它做两件事:
|
||||
|
||||
* For loading the list of all phones into the phone list component
|
||||
|
@ -1865,7 +1865,7 @@ code-example(format="").
|
|||
have these explicit selectors. This one will match elements with the name `phone-list`,
|
||||
just like the Angular 1 version did.
|
||||
|
||||
`selector`属性是一个CSS选择器,用来定义组件应该被放在页面的哪儿。在Angular 1,我们基于组件名字来匹配,
|
||||
`selector`属性是一个CSS选择器,用来定义组件应该被放在页面的哪。在Angular 1,我们基于组件名字来匹配,
|
||||
但是在Angular 2中,我们要有一个专门指定的选择器。本组件将会对应元素名字`phone-list`,和Angular 1版本一样。
|
||||
|
||||
We now also need to convert the template of this component into Angular 2 syntax.
|
||||
|
@ -2458,7 +2458,7 @@ code-example(format="").
|
|||
counterparts are switched. The specs for the checkmark pipe are probably the most straightforward,
|
||||
as the pipe has no dependencies:
|
||||
|
||||
如果产品代码被切换到了Angular 2,单元测试文件本身也需要切换过来。对勾儿(checkmark)管道的规约可能是最简单的,因为它没有任何依赖:
|
||||
如果产品代码被切换到了Angular 2,单元测试文件本身也需要切换过来。对勾(checkmark)管道的规约可能是最简单的,因为它没有任何依赖:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.spec.ts', null, 'app/core/checkmark/checkmark.pipe.spec.ts')
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ include ../_util-fns
|
|||
and for loading that code from a server into a browser.
|
||||
|
||||
[**Webpack**](https://webpack.github.io/)是一个广受欢迎的模块打包器,
|
||||
这个工具用来把程序源码打包到一些方便易用的_块儿_中,以便把这些代码从服务器加载到浏览器中。
|
||||
这个工具用来把程序源码打包到一些方便易用的_块_中,以便把这些代码从服务器加载到浏览器中。
|
||||
|
||||
It's an excellent alternative to the *SystemJS* approach we use throughout the documentation.
|
||||
In this guide we get a taste of Webpack and how to use it with Angular 2 applications.
|
||||
|
@ -74,14 +74,14 @@ include ../_util-fns
|
|||
A bundle can include JavaScript, CSS styles, HTML, and almost any other kind of file.
|
||||
|
||||
Webpack是一个强力的模块打包器。
|
||||
所谓_包儿(bundle)_就是一个JavaScript文件,它把一堆_资源(assets)_合并在一起,以便它们可以在同一个文件请求中发回给客户端。
|
||||
包儿中可以包含JavaScript、CSS样式、HTML以及很多其它类型的文件。
|
||||
所谓_包(bundle)_就是一个JavaScript文件,它把一堆_资源(assets)_合并在一起,以便它们可以在同一个文件请求中发回给客户端。
|
||||
包中可以包含JavaScript、CSS样式、HTML以及很多其它类型的文件。
|
||||
|
||||
Webpack roams over your application source code,
|
||||
looking for `import` statements, building a dependency graph, and emitting one (or more) _bundles_.
|
||||
With plugin "loaders" Webpack can preprocess and minify different non-JavaScript files such as TypeScript, SASS, and LESS files.
|
||||
|
||||
Webpack会遍历你应用中的所有源码,查找`import`语句,构建出依赖图谱,并产出一个(或多个)_包儿_。
|
||||
Webpack会遍历你应用中的所有源码,查找`import`语句,构建出依赖图谱,并产出一个(或多个)_包_。
|
||||
通过“加载器(loaders)”插件,Webpack可以对各种非JavaScript文件进行预处理和最小化(Minify),比如TypeScript、SASS和LESS文件等。
|
||||
|
||||
We determine what Webpack does and how it does it with a JavaScript configuration file, `webpack.config.js`.
|
||||
|
@ -114,12 +114,12 @@ a(id="entries-outputs")
|
|||
Here it sees that we're importing *@angular/core* so it adds that to its dependency list for (potential) inclusion in the bundle.
|
||||
It opens *@angular/core* and follows _its_ network of `import` statements until it has build the complete dependency graph from `app.ts` down.
|
||||
|
||||
这里,Webpack看到我们正在导入*@angular/core*,于是就这个文件加入到它的依赖列表里,为(有可能)把该文件打进包儿中做准备。
|
||||
这里,Webpack看到我们正在导入*@angular/core*,于是就这个文件加入到它的依赖列表里,为(有可能)把该文件打进包中做准备。
|
||||
它打开*@angular/core*并追踪由_该文件的_`import`语句构成的网络,直到构建出从`app.ts`往下的整个依赖图谱。
|
||||
|
||||
Then it **outputs** these files to the `app.js` _bundle file_ designated in configuration:
|
||||
|
||||
然后它把这些文件**输出**到当前配置所指定的_包儿文件_`app.js`中:
|
||||
然后它把这些文件**输出**到当前配置所指定的_包文件_`app.js`中:
|
||||
|
||||
+makeExample('webpack/ts-snippets/webpack.config.snippets.ts', 'one-output', 'webpack.config.js (single output)')(format=".")
|
||||
|
||||
|
@ -127,17 +127,17 @@ a(id="entries-outputs")
|
|||
This `app.js` output bundle is a single JavaScript file that contains our application source and its dependencies.
|
||||
We'll load it later with a <script> tag in our index.html.
|
||||
|
||||
这个`app.js`输出包儿是个单一的JavaScript文件,它包含程序的源码及其所有依赖。
|
||||
这个`app.js`输出包是个单一的JavaScript文件,它包含程序的源码及其所有依赖。
|
||||
后面我们将在`index.html`中用`<script>`标签来加载它。
|
||||
|
||||
#### Multiple bundles
|
||||
|
||||
#### 多重包儿
|
||||
#### 多重包
|
||||
|
||||
We probably do not want one giant bundle of everything.
|
||||
We'll likely prefer to separate our volatile application app code from comparatively stable vendor code modules.
|
||||
|
||||
我们可能不会希望把所有东西打进一个巨型包儿,而更喜欢把多变的应用代码从相对稳定的第三方提供商模块中分离出来。
|
||||
我们可能不会希望把所有东西打进一个巨型包,而更喜欢把多变的应用代码从相对稳定的第三方提供商模块中分离出来。
|
||||
|
||||
We change the configuration so that we have two entry points, `app.ts` and `vendor.ts`:
|
||||
|
||||
|
@ -149,7 +149,7 @@ a(id="entries-outputs")
|
|||
and emits *two* bundle files, one called `app.js` containing only our application code and
|
||||
another called `vendor.js` with all the vendor dependencies.
|
||||
|
||||
Webpack会构造出两个独立的依赖图谱,并产出*两个*包儿文件:一个叫做`app.js`,它只包含我们的应用代码;另一个叫做`vendor.js`,它包含所有的提供商依赖。
|
||||
Webpack会构造出两个独立的依赖图谱,并产出*两个*包文件:一个叫做`app.js`,它只包含我们的应用代码;另一个叫做`vendor.js`,它包含所有的提供商依赖。
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
|
@ -329,7 +329,7 @@ a(id="common-configuration")
|
|||
:marked
|
||||
We are splitting our application into three bundles:
|
||||
|
||||
我们正在把应用拆成三个包儿:
|
||||
我们正在把应用拆成三个包:
|
||||
|
||||
* polyfills - the standard polyfills we require to run Angular 2 applications in most modern browsers.
|
||||
|
||||
|
@ -433,12 +433,12 @@ a(id="commons-chunk-plugin")
|
|||
|
||||
We want the `app.js` bundle to contain only app code and the `vendor.js` bundle to contain only the vendor code.
|
||||
|
||||
我们希望`app.js`包儿中只包含应用代码,而`vendor.js`包中只包含提供商代码。
|
||||
我们希望`app.js`包中只包含应用代码,而`vendor.js`包中只包含提供商代码。
|
||||
|
||||
Our application code `imports` vendor code. Webpack is not smart enough to keep the vendor code out of the `app.js` bundle.
|
||||
We rely on the `CommonsChunkPlugin` to do that job.
|
||||
|
||||
应用代码中`import`了提供商代码。Webpack还没有智能到自动把提供商代码排除在`app.js`包儿之外。
|
||||
应用代码中`import`了提供商代码。Webpack还没有智能到自动把提供商代码排除在`app.js`包之外。
|
||||
`CommonsChunkPlugin`插件能完成此工作。
|
||||
|
||||
.l-sub-section
|
||||
|
@ -447,7 +447,7 @@ a(id="commons-chunk-plugin")
|
|||
Where Webpack finds that `app` has shared dependencies with `vendor`, it removes them from `app`.
|
||||
It would do the same if `vendor` and `polyfills` had shared dependencies (which they don't).
|
||||
|
||||
这里标记出了三个_块儿_之间的等级体系:`app` -> `vendor` -> `polyfills`。
|
||||
这里标记出了三个_块_之间的等级体系:`app` -> `vendor` -> `polyfills`。
|
||||
当Webpack发现`app`与`vendor`有共享依赖时,就把它们从`app`中移除。
|
||||
在`vendor`和`polyfills`之间有共享依赖时也同样如此(虽然它们没啥可共享的)。
|
||||
|
||||
|
@ -503,7 +503,7 @@ a(id="development-configuration")
|
|||
the dev server keeps all bundles in memory; it doesn't write them to disk.
|
||||
So we won't find any files in the `dist` folder (at least not any generated from `this development build`).
|
||||
|
||||
虽然我们告诉Webpack把输出包儿放到`dist`目录,但实际上开发服务器把这些包儿都放在了内存里,而不会把它们写到硬盘中。
|
||||
虽然我们告诉Webpack把输出包放到`dist`目录,但实际上开发服务器把这些包都放在了内存里,而不会把它们写到硬盘中。
|
||||
所以在`dist`目录下是找不到任何文件的(至少现在这个开发环境下构建时没有)。
|
||||
|
||||
|
||||
|
@ -516,7 +516,7 @@ a(id="development-configuration")
|
|||
Our CSS are buried inside our Javascript bundles by default. The `ExtractTextPlugin` extracts them into
|
||||
external `.css` files that the `HtmlWebpackPlugin` inscribes as <link> tags into the `index.html`.
|
||||
|
||||
我们这些CSS默认情况下会被埋没在JavaScript包儿中。`ExtractTextPlugin`会把它们提取成外部`.css`文件,
|
||||
我们这些CSS默认情况下会被埋没在JavaScript包中。`ExtractTextPlugin`会把它们提取成外部`.css`文件,
|
||||
这样`HtmlWebpackPlugin`插件就会转而把一个<link>标签写进`index.html`了。
|
||||
|
||||
Refer to the Webpack documentation for details on these and other configuration options in this file
|
||||
|
@ -550,7 +550,7 @@ a(id="production-configuration")
|
|||
|
||||
This time the output bundle files are physically placed in the `dist` folder.
|
||||
|
||||
这次,输出的包儿文件就被真的放到`dist`目录下了。
|
||||
这次,输出的包文件就被真的放到`dist`目录下了。
|
||||
|
||||
Webpack generates file names with cache-busting hash.
|
||||
Thanks to the `HtmlWebpackPlugin` we don't have to update the `index.html` file when the hashes changes.
|
||||
|
@ -567,7 +567,7 @@ a(id="production-configuration")
|
|||
* **DedupePlugin** - detects identical (and nearly identical) files and removes them from the output.
|
||||
* **DedupePlugin** - 检测完全相同(以及几乎完全相同)的文件,并把它们从输出中移除。
|
||||
* **UglifyJsPlugin** - minifies the bundles.
|
||||
* **UglifyJsPlugin** - 最小化(minify)生成的包儿。
|
||||
* **UglifyJsPlugin** - 最小化(minify)生成的包。
|
||||
* **ExtractTextPlugin** - extracts embedded css as external files, adding cache-busting hash to the filename.
|
||||
* **ExtractTextPlugin** - 把内嵌的css抽取成外部文件,并为其文件名添加“缓存无效哈希”。
|
||||
* **DefinePlugin** - use to define environment variables that we can reference within our application.
|
||||
|
|
|
@ -3,7 +3,7 @@ include ../_util-fns
|
|||
:marked
|
||||
In this chapter we'll setup the environment for testing our sample application and write a few easy Jasmine tests of the app's simplest parts.
|
||||
|
||||
本章中,我们将为范例应用设置测试环境,并针对应用程序中最简单的部分,写几个容易点儿的Jasmine测试。
|
||||
本章中,我们将为范例应用设置测试环境,并针对应用程序中最简单的部分,写几个容易点的Jasmine测试。
|
||||
|
||||
We'll learn:
|
||||
|
||||
|
@ -296,7 +296,7 @@ code-example(format="" language="html").
|
|||
|
||||
We add module loading support in four steps:
|
||||
|
||||
我们要通过四步儿来添加对模块加载的支持。
|
||||
我们要通过四步来添加对模块加载的支持。
|
||||
|
||||
1. add the *SystemJS* module management library
|
||||
|
||||
|
|
|
@ -310,7 +310,7 @@ figure.image-display
|
|||
:marked
|
||||
The glorious green is back with us again!
|
||||
|
||||
我们光荣的绿条儿又回来了!
|
||||
我们光荣的绿条又回来了!
|
||||
|
||||
We tried a bit of test driven development and it seems to have guided us to success.
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ code-example(language="bash").
|
|||
is not reflected in the `<h2>`. We won't get the desired behavior
|
||||
with a one-way binding to `<input>`.
|
||||
|
||||
在浏览器中,我们看到英雄的名字显示成一个`<input>`文本框。但看起来还是有点儿不太对劲。
|
||||
在浏览器中,我们看到英雄的名字显示成一个`<input>`文本框。但看起来还是有点不太对劲。
|
||||
当修改名字时,我们的改动并没有反映到`<h2>`中。使用单向数据绑定,我们没法实现所期望的这种行为。
|
||||
|
||||
### Two-Way Binding
|
||||
|
@ -237,7 +237,7 @@ code-example(language="bash").
|
|||
|
||||
在我们让**表单输入**支持双向数据绑定之前,我们得先导入`FormsModule`模块。
|
||||
只要把它添加到`NgModule`装饰器的`imports`数组中就可以了,该数组是应用中用到的外部模块列表。
|
||||
这样我们就引入了包括`ngModel`在内的表单依赖包儿。
|
||||
这样我们就引入了包括`ngModel`在内的表单依赖捆。
|
||||
|
||||
+makeExample('toh-1/ts/app/app.module.ts', '', 'app.module.ts (FormsModule import)')
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ code-example(language="bash").
|
|||
first and display mock heroes.
|
||||
|
||||
`HEROES`变量是一个由`Hero`类的实例构成的数组,我们在第一部分定义过它。
|
||||
我们当然希望从一个Web服务中获取这个英雄列表,但别急,我们得把步子迈得小一点儿 —— 先用一组Mock(模拟)出来的英雄。
|
||||
我们当然希望从一个Web服务中获取这个英雄列表,但别急,我们得把步子迈得小一点 —— 先用一组Mock(模拟)出来的英雄。
|
||||
|
||||
### Exposing heroes
|
||||
|
||||
|
@ -144,8 +144,8 @@ code-example(language="bash").
|
|||
and display them individually.
|
||||
We’ll need some help from Angular to do this. Let’s do this step by step.
|
||||
|
||||
我们想要把组件中的`heroes`数组绑定到模板中,迭代并逐个儿显示他们。
|
||||
这下,我们就得借Angular的帮助来完成它了。我们来一步步儿实现它!
|
||||
我们想要把组件中的`heroes`数组绑定到模板中,迭代并逐个显示他们。
|
||||
这下,我们就得借Angular的帮助来完成它了。我们来一步步实现它!
|
||||
|
||||
First modify the `<li>` tag by adding the built-in directive `*ngFor`.
|
||||
|
||||
|
@ -175,7 +175,7 @@ code-example(language="bash").
|
|||
“*take each hero in the `heroes` array, store it in the local `hero` variable,
|
||||
and make it available to the corresponding template instance*”.
|
||||
|
||||
引号中赋值给`ngFor`的那段儿文本表示“*从`heroes`数组中取出每个英雄,存入一个局部的`hero`变量,并让它在相应的模板实例中可用*”。
|
||||
引号中赋值给`ngFor`的那段文本表示“*从`heroes`数组中取出每个英雄,存入一个局部的`hero`变量,并让它在相应的模板实例中可用*”。
|
||||
|
||||
The `let` keyword before "hero" identifies `hero` as a template input variable.
|
||||
We can reference this variable within the template to access a hero’s properties.
|
||||
|
@ -319,7 +319,7 @@ code-example(language="bash").
|
|||
|
||||
Our component doesn’t have a “selected hero” yet either. We’ll start there.
|
||||
|
||||
我们的组件还没有用来表示“当前选中的英雄”的变量,我们就从这一步儿开始。
|
||||
我们的组件还没有用来表示“当前选中的英雄”的变量,我们就从这一步开始。
|
||||
|
||||
### Expose the selected hero
|
||||
|
||||
|
|
|
@ -464,7 +464,7 @@ a#child-component
|
|||
|
||||
We're getting closer. But something isn't quite right.
|
||||
|
||||
我们就快完成了,但还有点事情不太对劲儿。
|
||||
我们就快完成了,但还有点事情不太对劲。
|
||||
|
||||
<a id="async"></a>
|
||||
|
||||
|
@ -581,7 +581,7 @@ a#child-component
|
|||
:marked
|
||||
Checkout the "[Take it slow](#slow)" appendix to see what the app might be like with a poor connection.
|
||||
|
||||
查看附件中的“[慢一点儿](#slow)”一节,来了解在较差的网络连接中这个应用会是什么样的。
|
||||
查看附件中的“[慢一点](#slow)”一节,来了解在较差的网络连接中这个应用会是什么样的。
|
||||
|
||||
:marked
|
||||
### Review the App Structure
|
||||
|
@ -680,7 +680,7 @@ a#child-component
|
|||
:marked
|
||||
### Appendix: Take it slow
|
||||
|
||||
### 附件:慢一点儿
|
||||
### 附件:慢一点
|
||||
|
||||
We can simulate a slow connection.
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ figure.image-display
|
|||
:marked
|
||||
## Where We Left Off
|
||||
|
||||
## 我们在哪儿
|
||||
## 我们在哪
|
||||
|
||||
Before we continue with our Tour of Heroes, let’s verify that we have the following structure after adding our hero service
|
||||
and hero detail component. If not, we’ll need to go back and follow the previous chapters.
|
||||
|
@ -437,7 +437,7 @@ block router-config-intro
|
|||
But where?
|
||||
|
||||
如果我们把路径`/heroes`粘贴到浏览器的地址栏,路由器会匹配到`'Heroes'`路由,并显示`HeroesComponent`组件。
|
||||
但问题是,该把它显示在哪儿呢?
|
||||
但问题是,该把它显示在哪呢?
|
||||
|
||||
We have to ***tell it where*** by adding a `<router-outlet>` element to the bottom of the template.
|
||||
`RouterOutlet` is one of the <span if-docs="ts">directives provided by</span> the `!{_RouterModuleVsRouterDirectives}`.
|
||||
|
@ -973,7 +973,7 @@ block extract-id
|
|||
That's acceptable in a demo. We'd guard against it in a real application,
|
||||
perhaps with the [!{_CanDeactivateGuard}](../api/!{_CanDeactivateGuardUri}.html).
|
||||
|
||||
回退太多步儿会跑出我们的应用。
|
||||
回退太多步会跑出我们的应用。
|
||||
在Demo中,这算不上问题。但在真实的应用中,我们需要对此进行防范。
|
||||
也许你该用[!{_CanDeactivateGuard}](../api/!{_CanDeactivateGuardUri}.html).。
|
||||
|
||||
|
@ -1253,7 +1253,7 @@ block heroes-component-cleanup
|
|||
|
||||
We've met all of the navigational requirements that propelled this chapter.
|
||||
|
||||
我们已经满足了在本章开头儿设定的所有导航需求。
|
||||
我们已经满足了在本章开头设定的所有导航需求。
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
|
@ -1505,7 +1505,7 @@ block file-tree-end
|
|||
We're still missing a key piece: remote data access.
|
||||
|
||||
我们有了很多用于构建应用的基石。
|
||||
但我们仍然缺少很关键的一块儿:远程数据存取。
|
||||
但我们仍然缺少很关键的一块:远程数据存取。
|
||||
|
||||
In the next chapter,
|
||||
we’ll replace our mock data with data retrieved from a server using http.
|
||||
|
|
|
@ -35,7 +35,7 @@ p 运行这部分的#[+liveExampleLink2('在线例子', 'toh-6')]。
|
|||
:marked
|
||||
## Where We Left Off
|
||||
|
||||
## 我们在哪儿
|
||||
## 我们在哪
|
||||
|
||||
In the [previous chapter](toh-pt5.html), we learned to navigate between the dashboard and the fixed heroes list, editing a selected hero along the way.
|
||||
That's our starting point for this chapter.
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
- Lion6868(来自 Github )
|
||||
- 阿泽(来自 Angular 中文社区)
|
||||
- Aruis(来自 Github )
|
||||
- Elderry(来自 Github )
|
||||
- 另外还有一些做好事不留名的活雷锋
|
||||
|
||||
想让你的名字也出现在这里吗?请提供[反馈、纠错](https://github.com/angular/angular-cn/issues)。
|
||||
|
|
Loading…
Reference in New Issue