review of architecture.jjade is completed.
This commit is contained in:
parent
5a0a53a022
commit
f3268b5191
|
@ -401,6 +401,7 @@ figure
|
||||||
|
|
||||||
在TypeScript中,**装饰器(decorator)**是附加元数据的简易途径。
|
在TypeScript中,**装饰器(decorator)**是附加元数据的简易途径。
|
||||||
下面就是`HeroListComponent`的一些元数据。
|
下面就是`HeroListComponent`的一些元数据。
|
||||||
|
|
||||||
+makeExample('architecture/ts/app/hero-list.component.ts', 'metadata', 'app/hero-list.component.ts (元数据)')
|
+makeExample('architecture/ts/app/hero-list.component.ts', 'metadata', 'app/hero-list.component.ts (元数据)')
|
||||||
:marked
|
:marked
|
||||||
Here we see the `@Component` decorator which (no surprise) identifies the class
|
Here we see the `@Component` decorator which (no surprise) identifies the class
|
||||||
|
@ -453,8 +454,8 @@ code-example(language="html").
|
||||||
so it can get the list of heroes to display. We'll get to dependency injection in a moment.
|
so it can get the list of heroes to display. We'll get to dependency injection in a moment.
|
||||||
|
|
||||||
* `providers` - 一个数组,包含组件所依赖的用于提供服务的*依赖注入供应商*。
|
* `providers` - 一个数组,包含组件所依赖的用于提供服务的*依赖注入供应商*。
|
||||||
这是我们告诉Angular,该组件的构造函数需要一个`HeroService`服务。所以组件才能获得英雄的列表数据,并显示出来。
|
这是一种方法,用来告诉Angular该组件的构造函数需要一个`HeroService`服务,这样组件可以从服务获得英雄的列表数据用来显示。
|
||||||
这样我们就在一瞬间完成了依赖注入。
|
我们一会儿就讲到了依赖注入。
|
||||||
figure
|
figure
|
||||||
img(src="/resources/images/devguide/architecture/template-metadata-component.png" alt="元数据" align="left" style="height:200px; margin-left:-40px;margin-right:10px" )
|
img(src="/resources/images/devguide/architecture/template-metadata-component.png" alt="元数据" align="left" style="height:200px; margin-left:-40px;margin-right:10px" )
|
||||||
:marked
|
:marked
|
||||||
|
@ -462,7 +463,7 @@ figure
|
||||||
to the component class definition. Angular discovers this metadata at runtime and thus knows how to do "the right thing".
|
to the component class definition. Angular discovers this metadata at runtime and thus knows how to do "the right thing".
|
||||||
|
|
||||||
`@Component`函数接收一个配置对象,并把它转换成元数据,附加到组件类的定义上。
|
`@Component`函数接收一个配置对象,并把它转换成元数据,附加到组件类的定义上。
|
||||||
Angular在运行期间会找出这份元数据,并因此知道该如何去“做正确的事”。
|
Angular在运行期间会找出这份元数据,并由此知道该如何去“做正确的事”。
|
||||||
|
|
||||||
The template, metadata, and component together describe the view.
|
The template, metadata, and component together describe the view.
|
||||||
|
|
||||||
|
@ -473,8 +474,9 @@ figure
|
||||||
we'll master as our Angular knowledge grows.
|
we'll master as our Angular knowledge grows.
|
||||||
|
|
||||||
我们也会沿用类似的风格,用其它元数据装饰器来指导Angular的行为。
|
我们也会沿用类似的风格,用其它元数据装饰器来指导Angular的行为。
|
||||||
`@Injectable`、`@Input`、`@Output`、`@RouterConfig`是一些最常用的装饰器。
|
`@Injectable`、`@Input`、`@Output`和`@RouterConfig`等是一些最常用的装饰器。
|
||||||
随着对Angular认识的逐步深化,我们也将逐步掌握它们。
|
随着对Angular认识的逐步深化,我们也将逐步掌握它们。
|
||||||
|
|
||||||
<br clear="all">
|
<br clear="all">
|
||||||
:marked
|
:marked
|
||||||
The architectural take-away is that we must add metadata to our code
|
The architectural take-away is that we must add metadata to our code
|
||||||
|
@ -487,12 +489,14 @@ figure
|
||||||
:marked
|
:marked
|
||||||
## Data Binding
|
## Data Binding
|
||||||
## 数据绑定
|
## 数据绑定
|
||||||
|
|
||||||
Without a framework, we would be responsible for pushing data values into the HTML controls and turning user responses
|
Without a framework, we would be responsible for pushing data values into the HTML controls and turning user responses
|
||||||
into actions and value updates. Writing such push/pull logic by hand is tedious, error-prone and a nightmare to
|
into actions and value updates. Writing such push/pull logic by hand is tedious, error-prone and a nightmare to
|
||||||
read as the experienced jQuery programmer can attest.
|
read as the experienced jQuery programmer can attest.
|
||||||
|
|
||||||
如果没有框架,我们就得自己把数据值推送到HTML控件中,并把用户的反馈转换成动作并更新值。
|
如果没有框架,我们就得自己把数据值推送到HTML控件中,并把用户的反馈转换成动作并更新值。
|
||||||
如果手工写代码来实现这些推/拉逻辑,肯定会枯燥乏味、容易出错,读起来简直是噩梦 —— 写过jQuery的程序员大概都对此深有体会。
|
如果手工写代码来实现这些推/拉逻辑,肯定会枯燥乏味、容易出错,读起来简直是噩梦 —— 写过jQuery的程序员大概都对此深有体会。
|
||||||
|
|
||||||
figure
|
figure
|
||||||
img(src="/resources/images/devguide/architecture/databinding.png" alt="数据绑定" style="width:220px; float:left; margin-left:-40px;margin-right:20px" )
|
img(src="/resources/images/devguide/architecture/databinding.png" alt="数据绑定" style="width:220px; float:left; margin-left:-40px;margin-right:20px" )
|
||||||
:marked
|
:marked
|
||||||
|
@ -507,6 +511,7 @@ figure
|
||||||
as indicated by the arrows in the diagram.
|
as indicated by the arrows in the diagram.
|
||||||
|
|
||||||
数据绑定的语法有四种形式。每种形式都有一个方向 —— 从DOM来、到DOM去、双向,就像图中的箭头所示意的。
|
数据绑定的语法有四种形式。每种形式都有一个方向 —— 从DOM来、到DOM去、双向,就像图中的箭头所示意的。
|
||||||
|
|
||||||
<br clear="all">
|
<br clear="all">
|
||||||
:marked
|
:marked
|
||||||
We saw three forms of data binding in our [example](#template) template:
|
We saw three forms of data binding in our [example](#template) template:
|
||||||
|
@ -516,14 +521,17 @@ figure
|
||||||
:marked
|
:marked
|
||||||
* The {{hero.name}} "[interpolation](displaying-data.html#interpolation)"
|
* The {{hero.name}} "[interpolation](displaying-data.html#interpolation)"
|
||||||
displays the component's `hero.name` property value within the `<div>` tags.
|
displays the component's `hero.name` property value within the `<div>` tags.
|
||||||
|
|
||||||
* {{hero.name}} "[插值表达式](displaying-data.html#interpolation):"在`<div>`标签中显示了组件的`hero.name`属性的值。
|
* {{hero.name}} "[插值表达式](displaying-data.html#interpolation):"在`<div>`标签中显示了组件的`hero.name`属性的值。
|
||||||
|
|
||||||
* The `[hero]` [property binding](template-syntax.html#property-binding) passes the `selectedHero` from
|
* The `[hero]` [property binding](template-syntax.html#property-binding) passes the `selectedHero` from
|
||||||
the parent `HeroListComponent` to the `hero` property of the child `HeroDetailComponent`.
|
the parent `HeroListComponent` to the `hero` property of the child `HeroDetailComponent`.
|
||||||
|
|
||||||
* `[hero]`[属性绑定](template-syntax.html#property-binding):把父组件`HeroListComponent`的`selectedHero`传到子组件`HeroDetailComponent`的`hero`属性中。
|
* `[hero]`[属性绑定](template-syntax.html#property-binding):把父组件`HeroListComponent`的`selectedHero`传到子组件`HeroDetailComponent`的`hero`属性中。
|
||||||
|
|
||||||
* The `(click)` [event binding](user-input.html#click) calls the Component's `selectHero` method when the user clicks
|
* The `(click)` [event binding](user-input.html#click) calls the Component's `selectHero` method when the user clicks
|
||||||
on a hero's name
|
on a hero's name
|
||||||
|
|
||||||
* `(click)`[事件绑定](user-input.html#click):当用户点击英雄的名字时,会调用组件的`selectHero`方法。
|
* `(click)`[事件绑定](user-input.html#click):当用户点击英雄的名字时,会调用组件的`selectHero`方法。
|
||||||
|
|
||||||
* **Two-way data binding** is an important fourth form
|
* **Two-way data binding** is an important fourth form
|
||||||
|
@ -540,12 +548,13 @@ figure
|
||||||
The user's changes also flow back to the component, resetting the property to the latest value,
|
The user's changes also flow back to the component, resetting the property to the latest value,
|
||||||
as with event binding.
|
as with event binding.
|
||||||
|
|
||||||
在双向绑定中,数据属性的值会从具有属性绑定的组件传到输入框。通过事件绑定把最近的值传给属性,用户的修改也能传回组件。
|
在双向绑定中,数据属性的值会从具有属性绑定的组件传到输入框。通过事件绑定,用户的修改被传回到组件,把属性值设置为最新的值。
|
||||||
|
|
||||||
Angular processes *all* data bindings once per JavaScript event cycle,
|
Angular processes *all* data bindings once per JavaScript event cycle,
|
||||||
depth-first from the root of the application component tree.
|
depth-first from the root of the application component tree.
|
||||||
|
|
||||||
Angular在每个JavaScript事件周期中一次性处理*所有的*数据绑定,它会从组件树的根部进行深度优先遍历来完成更新。
|
Angular在每个JavaScript事件周期中一次性处理*所有的*数据绑定,它会从组件树的根部开始。进行深度-优先的往上更新。
|
||||||
|
|
||||||
figure
|
figure
|
||||||
img(src="/resources/images/devguide/architecture/component-databinding.png" alt="数据绑定" style="float:left; width:300px; margin-left:-40px;margin-right:10px" )
|
img(src="/resources/images/devguide/architecture/component-databinding.png" alt="数据绑定" style="float:left; width:300px; margin-left:-40px;margin-right:10px" )
|
||||||
:marked
|
:marked
|
||||||
|
@ -553,7 +562,8 @@ figure
|
||||||
but it's clear from these examples that data binding plays an important role in communication
|
but it's clear from these examples that data binding plays an important role in communication
|
||||||
between a template and its component ...
|
between a template and its component ...
|
||||||
|
|
||||||
虽然我们还没看懂所有细节,但从这些范例中至少弄明白一点:数据绑定在模板与相应组件的通讯中扮演了一个很重要的角色。
|
虽然还不清楚所有细节,但从我们从这些范例中至少弄明白一点:数据绑定在模板与相应组件的交互中扮演了一个很重要的角色。
|
||||||
|
|
||||||
<br clear="all">
|
<br clear="all">
|
||||||
figure
|
figure
|
||||||
img(src="/resources/images/devguide/architecture/parent-child-binding.png" alt="父/子绑定" style="float:left; width:300px; margin-left:-40px;margin-right:10px" )
|
img(src="/resources/images/devguide/architecture/parent-child-binding.png" alt="父/子绑定" style="float:left; width:300px; margin-left:-40px;margin-right:10px" )
|
||||||
|
@ -561,25 +571,29 @@ figure
|
||||||
... ***and*** between parent and child components
|
... ***and*** between parent and child components
|
||||||
|
|
||||||
……在父组件与子组件的通讯中***也同样如此***。
|
……在父组件与子组件的通讯中***也同样如此***。
|
||||||
|
|
||||||
<br clear="all">
|
<br clear="all">
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
<a id="directive"></a>
|
<a id="directive"></a>
|
||||||
:marked
|
:marked
|
||||||
## The Directive
|
## The Directive
|
||||||
|
|
||||||
## 指令
|
## 指令
|
||||||
|
|
||||||
figure
|
figure
|
||||||
img(src="/resources/images/devguide/architecture/directive.png" alt="父与子" style="float:left; width:150px; margin-left:-40px;margin-right:10px" )
|
img(src="/resources/images/devguide/architecture/directive.png" alt="父与子" style="float:left; width:150px; margin-left:-40px;margin-right:10px" )
|
||||||
:marked
|
:marked
|
||||||
Our Angular templates are *dynamic*. When Angular renders them, it transforms the DOM
|
Our Angular templates are *dynamic*. When Angular renders them, it transforms the DOM
|
||||||
according to the instructions given by a **directive**.
|
according to the instructions given by a **directive**.
|
||||||
|
|
||||||
我们的Angular模板是*动态的*。当Angular渲染它们时,它会根据**指令**中提供的操作指南对DOM进行修改。
|
我们的Angular模板是*动态的*。当Angular渲染它们时,它会根据**指令**提供的操作指南对DOM进行修改。
|
||||||
|
|
||||||
A directive is a class with directive metadata. In TypeScript we'd apply the `@Directive` decorator
|
A directive is a class with directive metadata. In TypeScript we'd apply the `@Directive` decorator
|
||||||
to attach metadata to the class.
|
to attach metadata to the class.
|
||||||
|
|
||||||
指令是一个带有“指令元数据”的类。在TypeScript中,我们要通过`@Directive`装饰器把元数据附加到类上。
|
指令是一个带有“指令元数据”的类。在TypeScript中,我们要通过`@Directive`装饰器把元数据附加到类上。
|
||||||
|
|
||||||
<br clear="all">
|
<br clear="all">
|
||||||
:marked
|
:marked
|
||||||
We already met one form of directive: the component. A component is a *directive-with-a-template*
|
We already met one form of directive: the component. A component is a *directive-with-a-template*
|
||||||
|
@ -593,7 +607,8 @@ figure
|
||||||
it is so distinctive and central to Angular applications that we chose
|
it is so distinctive and central to Angular applications that we chose
|
||||||
to separate the component from the directive in our architectural overview.
|
to separate the component from the directive in our architectural overview.
|
||||||
|
|
||||||
虽然**组件从技术角度说就是一个指令**,但它是如此与众不同,并在Angular中位于中心地位,以至于我们选择把它和指令分别画在我们的架构视图中。
|
虽然**组件从技术角度说就是一个指令**,但组件非常独特,并在Angular中位于中心地位,以至于我们在架构介绍中,把组件从指令中单独开来。
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
There are two *other* kinds of directives as well that we call "structural" and "attribute" directives.
|
There are two *other* kinds of directives as well that we call "structural" and "attribute" directives.
|
||||||
|
|
||||||
|
@ -611,11 +626,15 @@ figure
|
||||||
We see two built-in structural directives at play in our [example](#template) template:
|
We see two built-in structural directives at play in our [example](#template) template:
|
||||||
|
|
||||||
我们在[范例](#template)模板中会看到两个内建的结构型指令。
|
我们在[范例](#template)模板中会看到两个内建的结构型指令。
|
||||||
|
|
||||||
+makeExample('architecture/ts/app/hero-list.component.1.html', 'structural')(format=".")
|
+makeExample('architecture/ts/app/hero-list.component.1.html', 'structural')(format=".")
|
||||||
:marked
|
:marked
|
||||||
* [`*ngFor`](displaying-data.html#ngFor) tells Angular to stamp out one `<div>` per hero in the `heroes` list.
|
* [`*ngFor`](displaying-data.html#ngFor) tells Angular to stamp out one `<div>` per hero in the `heroes` list.
|
||||||
|
|
||||||
* [`*ngFor`](displaying-data.html#ngFor)告诉Angular为`heroes`列表中的每个英雄生成一个`<div>`标签。
|
* [`*ngFor`](displaying-data.html#ngFor)告诉Angular为`heroes`列表中的每个英雄生成一个`<div>`标签。
|
||||||
|
|
||||||
* [`*ngIf`](displaying-data.html#ngIf) includes the `HeroDetail` component only if a selected hero exists.
|
* [`*ngIf`](displaying-data.html#ngIf) includes the `HeroDetail` component only if a selected hero exists.
|
||||||
|
|
||||||
* [`*ngIf`](displaying-data.html#ngIf)表示只有在已经选择了一个英雄时才会包含`HeroDetail`组件。
|
* [`*ngIf`](displaying-data.html#ngIf)表示只有在已经选择了一个英雄时才会包含`HeroDetail`组件。
|
||||||
|
|
||||||
**Attribute** directives alter the appearance or behavior of an existing element.
|
**Attribute** directives alter the appearance or behavior of an existing element.
|
||||||
|
@ -626,12 +645,13 @@ figure
|
||||||
The `ngModel` directive, which implements two-way data binding, is an example of an attribute directive.
|
The `ngModel` directive, which implements two-way data binding, is an example of an attribute directive.
|
||||||
|
|
||||||
`ngModel`指令就是Attribute型指令的一个例子,它实现了双向数据绑定。
|
`ngModel`指令就是Attribute型指令的一个例子,它实现了双向数据绑定。
|
||||||
|
|
||||||
+makeExample('architecture/ts/app/hero-detail.component.html', 'ngModel')(format=".")
|
+makeExample('architecture/ts/app/hero-detail.component.html', 'ngModel')(format=".")
|
||||||
:marked
|
:marked
|
||||||
It modifies the behavior of an existing element (typically an `<input>`)
|
It modifies the behavior of an existing element (typically an `<input>`)
|
||||||
by setting its display value property and responding to change events.
|
by setting its display value property and responding to change events.
|
||||||
|
|
||||||
它修改了现有元素(典型的是`<input>`)的行为,让它显示属性值,并从change事件中得到回应。
|
它修改了现有元素(典型的是`<input>`)的行为:它设置了显示属性值,并对change事件做出相应回应。
|
||||||
|
|
||||||
Angular ships with a few other directives that either alter the layout structure
|
Angular ships with a few other directives that either alter the layout structure
|
||||||
(e.g. [ngSwitch](template-syntax.html#ngSwitch))
|
(e.g. [ngSwitch](template-syntax.html#ngSwitch))
|
||||||
|
@ -643,46 +663,57 @@ figure
|
||||||
|
|
||||||
And of course we can write our own directives.
|
And of course we can write our own directives.
|
||||||
|
|
||||||
而且,当然,我们还能写自己的指令。
|
当然,我们也能编写自己的指令。
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
<a id="service"></a>
|
<a id="service"></a>
|
||||||
:marked
|
:marked
|
||||||
## The Service
|
## The Service
|
||||||
|
|
||||||
## 服务
|
## 服务
|
||||||
|
|
||||||
figure
|
figure
|
||||||
img(src="/resources/images/devguide/architecture/service.png" alt="服务" style="float:left; margin-left:-40px;margin-right:10px" )
|
img(src="/resources/images/devguide/architecture/service.png" alt="服务" style="float:left; margin-left:-40px;margin-right:10px" )
|
||||||
:marked
|
:marked
|
||||||
"Service" is a broad category encompassing any value, function or feature that our application needs.
|
"Service" is a broad category encompassing any value, function or feature that our application needs.
|
||||||
|
|
||||||
“服务”分为很多种,包括:值、函数,以及应用所需的任何特性。
|
“服务”分为很多种,包括:值、函数,以及应用所需的特性。
|
||||||
|
|
||||||
Almost anything can be a service.
|
Almost anything can be a service.
|
||||||
A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.
|
A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.
|
||||||
|
|
||||||
几乎任何东西都可以是一个服务。
|
几乎任何东西都可以是一个服务。
|
||||||
典型的服务是一个类,具有专注的、经过良好定义的用途。它应该做一些具体的事情,并做好。
|
典型的服务是一个类,具有专注的、良好定义的用途。它应该做一件具体的事情,把它做好。
|
||||||
<br clear="all">
|
<br clear="all">
|
||||||
:marked
|
:marked
|
||||||
Examples include:
|
Examples include:
|
||||||
|
|
||||||
例如:
|
例如:
|
||||||
|
|
||||||
* logging service
|
* logging service
|
||||||
|
|
||||||
* 日志服务
|
* 日志服务
|
||||||
|
|
||||||
* data service
|
* data service
|
||||||
|
|
||||||
* 数据服务
|
* 数据服务
|
||||||
|
|
||||||
* message bus
|
* message bus
|
||||||
|
|
||||||
* 消息总线
|
* 消息总线
|
||||||
|
|
||||||
* tax calculator
|
* tax calculator
|
||||||
|
|
||||||
* 税款计算器
|
* 税款计算器
|
||||||
|
|
||||||
* application configuration
|
* application configuration
|
||||||
|
|
||||||
* 应用程序配置
|
* 应用程序配置
|
||||||
|
|
||||||
There is nothing specifically *Angular* about services. Angular itself has no definition of a *service*.
|
There is nothing specifically *Angular* about services. Angular itself has no definition of a *service*.
|
||||||
There is no *ServiceBase* class.
|
There is no *ServiceBase* class.
|
||||||
|
|
||||||
Angular对于服务没什么特别的要求。
|
服务没有什么特别属于Angular的特征。Angular本身对于服务也没有什么定义。
|
||||||
Angular本身对于服务也没有什么定义。
|
|
||||||
它甚至都没有*ServiceBase*类。
|
它甚至都没有*ServiceBase*类。
|
||||||
|
|
||||||
Yet services are fundamental to any Angular application.
|
Yet services are fundamental to any Angular application.
|
||||||
|
@ -692,13 +723,15 @@ figure
|
||||||
Here's an example of a service class that logs to the browser console
|
Here's an example of a service class that logs to the browser console
|
||||||
|
|
||||||
这里是一个“服务”类的范例,用于把日志记录到浏览器的控制台:
|
这里是一个“服务”类的范例,用于把日志记录到浏览器的控制台:
|
||||||
|
|
||||||
+makeExample('architecture/ts/app/logger.service.ts', 'class', 'app/logger.service.ts (只有类)')(format=".")
|
+makeExample('architecture/ts/app/logger.service.ts', 'class', 'app/logger.service.ts (只有类)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Here's a `HeroService` that fetches heroes and returns them in a resolved [promise](http://exploringjs.com/es6/ch_promises.html).
|
Here's a `HeroService` that fetches heroes and returns them in a resolved [promise](http://exploringjs.com/es6/ch_promises.html).
|
||||||
The `HeroService` depends on the `LoggerService` and another `BackendService` that handles the server communication grunt work.
|
The `HeroService` depends on the `LoggerService` and another `BackendService` that handles the server communication grunt work.
|
||||||
|
|
||||||
下面是一个`HeroService`类,用于获取英雄数据,并通过一个已解决的[承诺Promise](http://exploringjs.com/es6/ch_promises.html)返回它们。
|
下面是一个`HeroService`类,用于获取英雄数据,并通过一个已解析的[承诺Promise](http://exploringjs.com/es6/ch_promises.html)返回它们。
|
||||||
`HeroService`还依赖于`LoggerService`和另一个用来处理服务器通讯工作的`BackendService`。
|
`HeroService`还依赖于`LoggerService`和另一个用来处理服务器通讯工作的`BackendService`。
|
||||||
|
|
||||||
+makeExample('architecture/ts/app/hero.service.ts', 'class', 'app/hero.service.ts (只有类)')(format=".")
|
+makeExample('architecture/ts/app/hero.service.ts', 'class', 'app/hero.service.ts (只有类)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Services are everywhere.
|
Services are everywhere.
|
||||||
|
@ -710,15 +743,15 @@ figure
|
||||||
They delegate such tasks to services.
|
They delegate such tasks to services.
|
||||||
|
|
||||||
我们的组件是服务的主要消费者。它们依赖服务来处理大多数“苦差事”。
|
我们的组件是服务的主要消费者。它们依赖服务来处理大多数“苦差事”。
|
||||||
它们不需要从服务器获得数据,它们不需要验证输入,它们不需要直接往控制台写日志。
|
它们自己不需要从服务器获得数据,不需要验证输入,不需要直接往控制台写日志。
|
||||||
它们只要把任务委托给这些服务。
|
它们把任务委托给服务。
|
||||||
|
|
||||||
A component's job is to enable the user experience and nothing more. It mediates between the view (rendered by the template)
|
A component's job is to enable the user experience and nothing more. It mediates between the view (rendered by the template)
|
||||||
and the application logic (which often includes some notion of a "model"). A good component presents
|
and the application logic (which often includes some notion of a "model"). A good component presents
|
||||||
properties and methods for data binding. It delegates everything non-trivial to services.
|
properties and methods for data binding. It delegates everything non-trivial to services.
|
||||||
|
|
||||||
组件的任务就是提供用户体验,仅此而已。它介于视图(由模板渲染)和应用逻辑(通常包括“模型model”的观念)之间。
|
组件的任务就是提供用户体验,仅此而已。它介于视图(由模板渲染)和应用逻辑(通常包括“模型model”的观念)之间。
|
||||||
设计良好的组件会提供属性和方法供数据绑定,而把那些不重要的事情都委托给服务。
|
设计良好的组件为数据绑定提供属性和方法,把那些其他对它们不重要的事情都委托给服务。
|
||||||
|
|
||||||
Angular doesn't *enforce* these principles.
|
Angular doesn't *enforce* these principles.
|
||||||
It won't complain if we write a "kitchen sink" component with 3000 lines.
|
It won't complain if we write a "kitchen sink" component with 3000 lines.
|
||||||
|
@ -729,13 +762,15 @@ figure
|
||||||
Angular does help us *follow* these principles by making it easy to factor our
|
Angular does help us *follow* these principles by making it easy to factor our
|
||||||
application logic into services and make those services available to components through *dependency injection*.
|
application logic into services and make those services available to components through *dependency injection*.
|
||||||
|
|
||||||
Angular帮助我们*追随*这些原则 —— 它让我们能更轻易的把应用逻辑拆分成组件,并通过*依赖注入*来让这些服务在组件中可用。
|
Angular帮助我们*追随*这些原则 —— 它让我们能更轻易的把应用逻辑拆分到服务,并通过*依赖注入*来在组件中使用这些服务。
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
<a id="dependency-injection"></a>
|
<a id="dependency-injection"></a>
|
||||||
:marked
|
:marked
|
||||||
## Dependency Injection
|
## Dependency Injection
|
||||||
|
|
||||||
## 依赖注入
|
## 依赖注入
|
||||||
|
|
||||||
figure
|
figure
|
||||||
img(src="/resources/images/devguide/architecture/dependency-injection.png" alt="服务" style="float:left; width:200px; margin-left:-40px;margin-right:10px" )
|
img(src="/resources/images/devguide/architecture/dependency-injection.png" alt="服务" style="float:left; width:200px; margin-left:-40px;margin-right:10px" )
|
||||||
:marked
|
:marked
|
||||||
|
@ -745,12 +780,13 @@ figure
|
||||||
|
|
||||||
“依赖注入”是提供类的新实例的一种方式,还负责处理好它所需的全部依赖。大多数依赖都是服务。
|
“依赖注入”是提供类的新实例的一种方式,还负责处理好它所需的全部依赖。大多数依赖都是服务。
|
||||||
Angular也使用依赖注入提供我们需要的组件,包括组件所需的服务。
|
Angular也使用依赖注入提供我们需要的组件,包括组件所需的服务。
|
||||||
|
|
||||||
<br clear="all">
|
<br clear="all">
|
||||||
:marked
|
:marked
|
||||||
In TypeScript, Angular can tell which services a component needs by looking at the types of its constructor parameters.
|
In TypeScript, Angular can tell which services a component needs by looking at the types of its constructor parameters.
|
||||||
For example, the constructor of our `HeroListComponent` needs the `HeroService`:
|
For example, the constructor of our `HeroListComponent` needs the `HeroService`:
|
||||||
|
|
||||||
借助TypeScript,Angular能通过查看构造函数的参数类型告诉组件需要哪些服务。
|
借助TypeScript,Angular能通过查看构造函数的参数类型,并得知组件需要哪些服务。
|
||||||
例如,我们`HeroListComponent`组件的构造函数需要`HeroService`:
|
例如,我们`HeroListComponent`组件的构造函数需要`HeroService`:
|
||||||
+makeExample('architecture/ts/app/hero-list.component.ts', 'ctor', 'app/hero-list.component (构造函数)')(format=".")
|
+makeExample('architecture/ts/app/hero-list.component.ts', 'ctor', 'app/hero-list.component (构造函数)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
|
@ -767,13 +803,14 @@ figure
|
||||||
This is what we mean by *dependency injection*.
|
This is what we mean by *dependency injection*.
|
||||||
|
|
||||||
注入器会维护一个服务实例的容器,存放着以前创建的实例。
|
注入器会维护一个服务实例的容器,存放着以前创建的实例。
|
||||||
如果容器中还没有所请求的服务实例,注入器就会创建一个,并且添加到容器中,然后把这个服务返回给Angular。
|
如果容器中还没有所请求的服务实例,注入器就会创建一个服务实例,并且添加到容器中,然后把这个服务返回给Angular。
|
||||||
当所有的服务都被解析完并返回时,Angular会以这些服务为参数去调用组件的构造函数。
|
当所有的服务都被解析完并返回时,Angular会以这些服务为参数去调用组件的构造函数。
|
||||||
这就是我们称其为 *依赖注入* 的原因。
|
这就是我们所说的*依赖注入* 。
|
||||||
|
|
||||||
The process of `HeroService` injection looks a bit like this:
|
The process of `HeroService` injection looks a bit like this:
|
||||||
|
|
||||||
`HeroService`注入的过程看起来有点像这样:
|
`HeroService`注入的过程看起来有点像这样:
|
||||||
|
|
||||||
figure
|
figure
|
||||||
img(src="/resources/images/devguide/architecture/injector-injects.png" alt="服务" )
|
img(src="/resources/images/devguide/architecture/injector-injects.png" alt="服务" )
|
||||||
:marked
|
:marked
|
||||||
|
@ -784,26 +821,28 @@ figure
|
||||||
In brief, we must have previously registered a **provider** of the `HeroService` with the `Injector`.
|
In brief, we must have previously registered a **provider** of the `HeroService` with the `Injector`.
|
||||||
A provider is something that can create or return a service, typically the service class itself.
|
A provider is something that can create or return a service, typically the service class itself.
|
||||||
|
|
||||||
简单的说,我们必须有以前通过注入器注册过的`HeroService`**供应商Provider**。
|
简单的说,我们必须有:之前通过注入器注册过的`HeroService`的**供应商Provider**。
|
||||||
供应商就是某些我们用来创建并返回服务的东西,通常就是这个“服务类”本身。
|
供应商可以创建并返回服务,通常返回的就是这个“服务类”本身。
|
||||||
|
|
||||||
We can register providers at any level of the application component tree.
|
We can register providers at any level of the application component tree.
|
||||||
We often do so at the root when we bootstrap the application so that
|
We often do so at the root when we bootstrap the application so that
|
||||||
the same instance of a service is available everywhere.
|
the same instance of a service is available everywhere.
|
||||||
|
|
||||||
我们可以在应用程序的组件树中任何级别上注册供应商。
|
我们可以在应用程序的组件树中任何级别上注册供应商。
|
||||||
我们通常在应用启动时注册在根组件上,以便此服务的同一个实例在任何地方都是可用的。
|
当我们需要一个服务的同一个实例在任何地方都是可用时,我们通常在应用引导程序中注册它。
|
||||||
|
|
||||||
+makeExample('architecture/ts/app/main.ts', 'bootstrap','app/main.ts (节选)')(format=".")
|
+makeExample('architecture/ts/app/main.ts', 'bootstrap','app/main.ts (节选)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Alternatively, we might register at a component level ...
|
Alternatively, we might register at a component level ...
|
||||||
|
|
||||||
或者,我们也可以把它注册在组件层……
|
或者,我们也可以把它注册在组件层……
|
||||||
|
|
||||||
+makeExample('architecture/ts/app/hero-list.component.ts', 'providers','app/hero-list.component.ts (节选)')(format=".")
|
+makeExample('architecture/ts/app/hero-list.component.ts', 'providers','app/hero-list.component.ts (节选)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
... in which case we get a new instance of the
|
... in which case we get a new instance of the
|
||||||
service with each new instance of that component.
|
service with each new instance of that component.
|
||||||
|
|
||||||
…… 在这种情况下,那个组件的每一个新实例都会有一个本服务的新实例。
|
…… 在这种情况下,那个组件的每一个新实例都会有一个(在该组件注册的)服务的新实例。
|
||||||
|
|
||||||
We've vastly over-simplified dependency injection for this overview.
|
We've vastly over-simplified dependency injection for this overview.
|
||||||
We can learn the full story in the [Dependency Injection](dependency-injection.html) chapter.
|
We can learn the full story in the [Dependency Injection](dependency-injection.html) chapter.
|
||||||
|
@ -814,56 +853,87 @@ figure
|
||||||
The points to remember are:
|
The points to remember are:
|
||||||
|
|
||||||
需要记住的要点是:
|
需要记住的要点是:
|
||||||
|
|
||||||
* dependency injection is wired into the framework and used everywhere.<br><br>
|
* dependency injection is wired into the framework and used everywhere.<br><br>
|
||||||
|
|
||||||
* 依赖注入渗透在整个框架中,并且随处可用。<br><br>
|
* 依赖注入渗透在整个框架中,并且随处可用。<br><br>
|
||||||
|
|
||||||
* the `Injector` is the main mechanism.
|
* the `Injector` is the main mechanism.
|
||||||
|
|
||||||
* 注入器`Injector`是本机制的核心。
|
* 注入器`Injector`是本机制的核心。
|
||||||
|
|
||||||
* an injector maintains a *container* of service instances that it created.
|
* an injector maintains a *container* of service instances that it created.
|
||||||
|
|
||||||
* 注入器负责维护一个*容器*,用于存放它创建过的服务实例。
|
* 注入器负责维护一个*容器*,用于存放它创建过的服务实例。
|
||||||
|
|
||||||
* an injector can create a new service instance using a *provider*.
|
* an injector can create a new service instance using a *provider*.
|
||||||
|
|
||||||
* 注入器能使用*供应商*创建一个新的服务实例。
|
* 注入器能使用*供应商*创建一个新的服务实例。
|
||||||
|
|
||||||
* a *provider* is a recipe for creating a service.
|
* a *provider* is a recipe for creating a service.
|
||||||
|
|
||||||
* *供应商*是一个用于创建服务的“配方”。
|
* *供应商*是一个用于创建服务的“配方”。
|
||||||
|
|
||||||
* we register *providers* with injectors.
|
* we register *providers* with injectors.
|
||||||
* 我们通过注入器注册*供应商*。
|
|
||||||
|
* 我们通过注入器来注册*供应商*。
|
||||||
|
|
||||||
<a id="other-stuff"></a>
|
<a id="other-stuff"></a>
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Wrap up
|
## Wrap up
|
||||||
|
|
||||||
## 总结
|
## 总结
|
||||||
|
|
||||||
We've learned just a bit about the eight main building blocks of an Angular application
|
We've learned just a bit about the eight main building blocks of an Angular application
|
||||||
|
|
||||||
我们学到的这些只是关于应用的八个主要构造块儿的一点皮毛
|
我们学到的这些只是关于应用的八个主要构造块的一点皮毛
|
||||||
|
|
||||||
1. [Module](#module)
|
1. [Module](#module)
|
||||||
1. [模块Module](#module)
|
|
||||||
|
1. [模块](#module)
|
||||||
|
|
||||||
1. [Component](#component)
|
1. [Component](#component)
|
||||||
1. [组件Component](#component)
|
|
||||||
|
1. [组件](#component)
|
||||||
|
|
||||||
1. [Template](#template)
|
1. [Template](#template)
|
||||||
1. [模板Template](#template)
|
|
||||||
|
1. [模板=](#template)
|
||||||
|
|
||||||
1. [Metadata](#metadata)
|
1. [Metadata](#metadata)
|
||||||
1. [元数据Metadata](#metadata)
|
|
||||||
|
1. [元数据=](#metadata)
|
||||||
|
|
||||||
1. [Data Binding](#data-binding)
|
1. [Data Binding](#data-binding)
|
||||||
1. [数据绑定Data Binding](#data-binding)
|
|
||||||
|
1. [数据绑定=](#data-binding)
|
||||||
|
|
||||||
1. [Directive](#directive)
|
1. [Directive](#directive)
|
||||||
1. [指令Directive](#directive)
|
|
||||||
|
1. [指令=](#directive)
|
||||||
|
|
||||||
1. [Service](#service)
|
1. [Service](#service)
|
||||||
1. [服务Service](#service)
|
|
||||||
|
1. [服务=](#service)
|
||||||
|
|
||||||
1. [Dependency Injection](#dependency-injection)
|
1. [Dependency Injection](#dependency-injection)
|
||||||
1. [依赖注入Dependency Injection](#dependency-injection)
|
|
||||||
|
1. [依赖注入=](#dependency-injection)
|
||||||
|
|
||||||
|
|
||||||
That's a foundation for everything else in an Angular application
|
That's a foundation for everything else in an Angular application
|
||||||
and it's more than enough to get going.
|
and it's more than enough to get going.
|
||||||
But it doesn't include everything we'll need or want to know.
|
But it doesn't include everything we'll need or want to know.
|
||||||
|
|
||||||
这是Angular应用中所有其它东西的基础。要继续向前,这已经绰绰有余了。
|
这是Angular应用中所有其它东西的基础,这些对开端(使用Angular 2)已经绰绰有余了。
|
||||||
但它仍然没有包含我们将要用到或想知道的全部。
|
但它仍然没有包含我们需要的或想知道的全部。
|
||||||
|
|
||||||
<a id="other-stuff"></a>
|
<a id="other-stuff"></a>
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## The Other Stuff
|
## The Other Stuff
|
||||||
|
|
||||||
## 其它东西
|
## 其它东西
|
||||||
|
|
||||||
Here is a brief, alphabetical list of other important Angular features and services.
|
Here is a brief, alphabetical list of other important Angular features and services.
|
||||||
|
@ -896,7 +966,7 @@ figure
|
||||||
>**Events** - The DOM raises events. So can components and services. Angular offers mechanisms for
|
>**Events** - The DOM raises events. So can components and services. Angular offers mechanisms for
|
||||||
publishing and subscribing to events including an implementation of the [RxJS Observable](https://github.com/zenparsing/es-observable) proposal.
|
publishing and subscribing to events including an implementation of the [RxJS Observable](https://github.com/zenparsing/es-observable) proposal.
|
||||||
|
|
||||||
>**事件Events** - DOM能触发事件,组件和服务也能。Angular提供的事件发布与订阅机制还包括[RxJS可观察Observable](https://github.com/zenparsing/es-observable)方案的一个实现。
|
>**事件Events** - DOM能触发事件,组件和服务也能。Angular提供的事件发布与订阅机制还包括[RxJS可观察Observable](https://github.com/zenparsing/es-observable)方案的一个实施。
|
||||||
|
|
||||||
>**[Forms](forms.html)** - Support complex data entry scenarios with HTML-based validation and dirty checking.
|
>**[Forms](forms.html)** - Support complex data entry scenarios with HTML-based validation and dirty checking.
|
||||||
|
|
||||||
|
@ -916,6 +986,7 @@ figure
|
||||||
this `currency` pipe expression,
|
this `currency` pipe expression,
|
||||||
|
|
||||||
>**[管道Pipes](pipes.html)** - 这种服务会转换值以供显示。我们可以把管道放在模板中,以增强用户体验。比如这个`currency`管道表达式,
|
>**[管道Pipes](pipes.html)** - 这种服务会转换值以供显示。我们可以把管道放在模板中,以增强用户体验。比如这个`currency`管道表达式,
|
||||||
|
|
||||||
<div style="margin-left:40px">
|
<div style="margin-left:40px">
|
||||||
code-example(language="javascript" linenumbers=".").
|
code-example(language="javascript" linenumbers=".").
|
||||||
price | currency:'USD':true
|
price | currency:'USD':true
|
||||||
|
@ -928,4 +999,4 @@ code-example(language="javascript" linenumbers=".").
|
||||||
>**[Testing](../testing/index.html)** - Angular provides a testing library for "unit testing" our application parts as they
|
>**[Testing](../testing/index.html)** - Angular provides a testing library for "unit testing" our application parts as they
|
||||||
interact with the Angular framework.
|
interact with the Angular framework.
|
||||||
|
|
||||||
>**[Testing](../testing/index.html)** - Angular提供了一个用于对我们应用中的各个部分进行“单元测试”的测试库,就像它们与Angular框架交互时一样。
|
>**[Testing](../testing/index.html)** - Angular提供了一个测试库,在程序各个部分与Angular框架交互同时,用来“单元测试”它们。
|
||||||
|
|
Loading…
Reference in New Issue