Merge remote-tracking branch 'cn/master'

This commit is contained in:
Zhicheng Wang 2016-04-15 22:34:27 +08:00
commit 2d56cd5831
2 changed files with 206 additions and 24 deletions

View File

@ -5,71 +5,99 @@ include ../_util-fns
especially if we'll need a great number of them, they're similar to each other, and they change frequently especially if we'll need a great number of them, they're similar to each other, and they change frequently
to meet rapidly changing business and regulatory requirements. to meet rapidly changing business and regulatory requirements.
我们不可能一直觉得手动编写表单和需要的工作量和时间成正比,特别是当我们需要编写大量的表单,他们非常类似,而且他们需要随着商务和政策需求的迅速变化而变化。
It may be more economical to create the forms dynamically, based on metadata that describe the business object model. It may be more economical to create the forms dynamically, based on metadata that describe the business object model.
基于商务对象模型里面的元数据,动态建立表单可能更加划算。
In this cookbook we show how to use `ngFormModel` to dynamically render a simple form with different control types and validation. In this cookbook we show how to use `ngFormModel` to dynamically render a simple form with different control types and validation.
It's a primitive start. It's a primitive start.
It might evolve to support a much richer variety of questions, more graceful rendering, and superior user experience. It might evolve to support a much richer variety of questions, more graceful rendering, and superior user experience.
All such greatness has humble beginnings. All such greatness has humble beginnings.
在本文中,我们会展示怎么利用`ngFormModel`动态渲染一个简单的表单, 包含不同类型控制器和验证规则。
这是一个原始的开始,任何伟大都是从谦卑开始的。我们可以在这个基础上添加种类丰富的问卷问题,更加优美的渲染和更优越的用户体验。
In our example we use a dynamic form to build an online application experience for heroes seeking employment. In our example we use a dynamic form to build an online application experience for heroes seeking employment.
The agency is constantly tinkering with the application process. The agency is constantly tinkering with the application process.
We can create the forms on the fly *without changing our application code*. We can create the forms on the fly *without changing our application code*.
在这个例子中,我们使用动态表单,为正在找工作的英雄们创建一个在线申请体验。中介在不断的修改申请流程。我们可以在*不修改程序*的情况下,动态即时的建立一个表格
<a id="toc"></a> <a id="toc"></a>
:marked :marked
## Table of contents ## Table of contents
## 目录
[问卷问题模型Question Model](#object-model)
[Question Model](#object-model) [表单组件Form Component](#form-component)
[Form Component](#form-component) [问卷元数据Questionnaire Metadata](#questionnaire-metadata)
[Questionnaire Metadata](#questionnaire-metadata) [动态模板Dynamic Template](#dynamic-template)
[Dynamic Template](#dynamic-template)
:marked :marked
**See the [live example](/resources/live-examples/cb-dynamic-form/ts/plnkr.html)**. **See the [live example](/resources/live-examples/cb-dynamic-form/ts/plnkr.html)**.
**请看[在线例子](/resources/live-examples/cb-dynamic-form/ts/plnkr.html)**.
.l-main-section .l-main-section
<a id="object-model"></a> <a id="object-model"></a>
:marked :marked
## Question Model ## Question Model
## 问卷问题模型
The first step is to define an object model that can describe all scenarios needed by the form functionality. The first step is to define an object model that can describe all scenarios needed by the form functionality.
The hero application process involves a form with a lot of questions. The hero application process involves a form with a lot of questions.
The "question" is the most fundamental object in the model. The "question" is the most fundamental object in the model.
第一步是定义一个对象模型,用来描述所有表单功能需要的场景。英雄申请流程涉及到一个有很多问卷问题的表单。问卷问题是最基础的对象模型。
We have created `QuestionBase` as the most fundamental question class. We have created `QuestionBase` as the most fundamental question class.
下面是我们建立的非常基础的问卷问题类,名叫`QuestionBase`。
+makeExample('cb-dynamic-form/ts/app/question-base.ts','','app/question-base.ts') +makeExample('cb-dynamic-form/ts/app/question-base.ts','','app/question-base.ts')
:marked :marked
From this base we derived two new classes in `TextboxQuestion` and `DropdownQuestion` that represent Textbox and Dropdown questions. From this base we derived two new classes in `TextboxQuestion` and `DropdownQuestion` that represent Textbox and Dropdown questions.
The idea is that the form will be bound to specific question types and render the appropriate controls dynamically. The idea is that the form will be bound to specific question types and render the appropriate controls dynamically.
在这个基础上,我们衍生了两个新类`TextboxQuestion` 和 `DropdownQuestion`,分别代表文本框和下拉框。这么做的初衷是,表单能动态的绑定特定的问卷问题类型,并动态渲染合适的控制器。
`TextboxQuestion` supports multiple html5 types like text, email, url etc via the `type` property. `TextboxQuestion` supports multiple html5 types like text, email, url etc via the `type` property.
`TextboxQuestion`通过`type`属性支持多种HTML5元素类型比如文本、邮件、网址等。
+makeExample('cb-dynamic-form/ts/app/question-textbox.ts',null,'app/question-textbox.ts')(format='.') +makeExample('cb-dynamic-form/ts/app/question-textbox.ts',null,'app/question-textbox.ts')(format='.')
:marked :marked
`DropdownQuestion` presents a list of choices in a select box. `DropdownQuestion` presents a list of choices in a select box.
`DropdownQuestion`代表一个拥有一个列表可选项目的选择框。
+makeExample('cb-dynamic-form/ts/app/question-dropdown.ts',null,'app/question-dropdown.ts')(format='.') +makeExample('cb-dynamic-form/ts/app/question-dropdown.ts',null,'app/question-dropdown.ts')(format='.')
:marked :marked
Next we have defined `QuestionControlService`, a simple service for transforming our questions to an ngForm control group. Next we have defined `QuestionControlService`, a simple service for transforming our questions to an ngForm control group.
In a nutshell, the control group consumes the metadata from the question model and allows us to specify default values and validation rules. In a nutshell, the control group consumes the metadata from the question model and allows us to specify default values and validation rules.
下一步,我们定义了`QuestionControlService`一个可以把我们的问卷问题转换为ngForm控制组的服务。简而言之这个ngForm控制组使用问卷模型的元数据允许我们制定默认值和验证规则。
+makeExample('cb-dynamic-form/ts/app/question-control.service.ts',null,'app/question-control.service.ts')(format='.') +makeExample('cb-dynamic-form/ts/app/question-control.service.ts',null,'app/question-control.service.ts')(format='.')
<a id="form-component"></a> <a id="form-component"></a>
:marked :marked
## Question form components ## Question form components
## 问卷表单组件
Now that we have defined the complete model we are ready to create components to represent the dynamic form. Now that we have defined the complete model we are ready to create components to represent the dynamic form.
现在我们已经有一个已定义的完整模型,我们可以创建一个动态表单的组件。
:marked :marked
`DynamicForm` is the entry point and the main container for the form. `DynamicForm` is the entry point and the main container for the form.
`DynamicForm`是我们表单的主要载体和切入口。
+makeTabs( +makeTabs(
`cb-dynamic-form/ts/app/dynamic-form.component.html, `cb-dynamic-form/ts/app/dynamic-form.component.html,
cb-dynamic-form/ts/app/dynamic-form.component.ts`, cb-dynamic-form/ts/app/dynamic-form.component.ts`,
@ -82,6 +110,8 @@ include ../_util-fns
The `<df-question>` tag matches the `DynamicFormQuestionComponent`, The `<df-question>` tag matches the `DynamicFormQuestionComponent`,
the component responsible for rendering the details of each _individual_ question based on values in the data-bound question object. the component responsible for rendering the details of each _individual_ question based on values in the data-bound question object.
它显示一个问卷问题的列表,每个问题都在`<df-question>`组件元素之内。`<df-question>`对应于`DynamicFormQuestionComponent`,该组件的作用是根据问卷问题对象的值来渲染每个问卷问题的细节。
+makeTabs( +makeTabs(
`cb-dynamic-form/ts/app/dynamic-form-question.component.html, `cb-dynamic-form/ts/app/dynamic-form-question.component.html,
cb-dynamic-form/ts/app/dynamic-form-question.component.ts`, cb-dynamic-form/ts/app/dynamic-form-question.component.ts`,
@ -94,50 +124,74 @@ include ../_util-fns
We only have two types of questions at this point but we can imagine many more. We only have two types of questions at this point but we can imagine many more.
The `ngSwitch` determines which type of question to display. The `ngSwitch` determines which type of question to display.
请注意,这个组件能代表模型里的任何问卷问题类型。目前,我们只有两种类型的问卷问题,但是我们可以添加更多类型。`ngSwitch`确定显示哪一个类型的问卷问题。
In both components we're relying on Angular's **ngFormModel** to connect the template HTML to the In both components we're relying on Angular's **ngFormModel** to connect the template HTML to the
underlying control objects, populated from the question model with display and validation rules. underlying control objects, populated from the question model with display and validation rules.
在两个组件中我们依赖Angular的**ngFormModel**来把模板HTML链接到底层控制对象该对象已经从问卷问题模型里获取了显示和验证规则
<a id="questionnaire-metadata"></a> <a id="questionnaire-metadata"></a>
:marked :marked
## Questionnaire data ## Questionnaire data
## 问卷数据
:marked :marked
`DynamicForm` expects the list of questions in the form of an array bound to `@Input() questions`. `DynamicForm` expects the list of questions in the form of an array bound to `@Input() questions`.
`DynamicForm`预期得到一个问题列表,该列表是一个关联到`@Input() questions`排列。
The set of questions we have defined for the job application is returned from the `QuestionService`. The set of questions we have defined for the job application is returned from the `QuestionService`.
In a real app we'd retrieve these questions from storage. In a real app we'd retrieve these questions from storage.
`QuestionService`返回我们在定义工作申请表的时候设定的这套问题。在一个真实的应用程序中,我们会从存储库里面提取。
The key point is that we control the hero job application questions entirely through the objects returned from `QuestionService`. The key point is that we control the hero job application questions entirely through the objects returned from `QuestionService`.
Questionnaire maintenance is a simple matter of adding, updating, and removing objects from the `questions` array. Questionnaire maintenance is a simple matter of adding, updating, and removing objects from the `questions` array.
最关键的点是,我们全部通过从`QuestionService`返回的对象,来控制英雄工作申请问卷。要维护问卷,我们要做的是非常简单的添加、更新和删除`问题`排列中的对象。
+makeExample('cb-dynamic-form/ts/app/question.service.ts','','app/question.service.ts') +makeExample('cb-dynamic-form/ts/app/question.service.ts','','app/question.service.ts')
:marked :marked
Finally, we display an instance of the form in the `AppComponent` shell. Finally, we display an instance of the form in the `AppComponent` shell.
最后,我们在`AppComponent`里面显示表单。
+makeExample('cb-dynamic-form/ts/app/app.component.ts','','app.component.ts') +makeExample('cb-dynamic-form/ts/app/app.component.ts','','app.component.ts')
<a id="dynamic-template"></a> <a id="dynamic-template"></a>
:marked :marked
## Dynamic Template ## Dynamic Template
## 动态模板
Although in this example we're modelling a job application for heroes, there are no references to any specific hero question Although in this example we're modelling a job application for heroes, there are no references to any specific hero question
outside the objects returned by `QuestionService`. outside the objects returned by `QuestionService`.
虽然在这个例子中,我们是在为英雄工作申请表建模,但是除了`QuestionService`返回的对象外,没有其他任何地方有指定英雄问卷相关的内容。
This is very important since it allows us to repurpose the components for any type of survey This is very important since it allows us to repurpose the components for any type of survey
as long as it's compatible with our *question* object model. as long as it's compatible with our *question* object model.
The key is the dynamic data binding of metadata used to render the form The key is the dynamic data binding of metadata used to render the form
without making any hardcoded assumptions about specific questions. without making any hardcoded assumptions about specific questions.
In addition to control metadata, we are also adding validation dynamically. In addition to control metadata, we are also adding validation dynamically.
这点非常重要的,因为只要与我们的*问卷*对象模型兼容,它允许我们为任何类型的调查重复使用这些组件。关键是运用动态数据绑定的元数据来渲染表单,不对问卷问题有任何硬性的假设。除了控制起元数据外,我们还可以动态添加验证规则。
The *Save* button is disabled until the form is in a valid state. The *Save* button is disabled until the form is in a valid state.
When the form is valid, we can click *Save* and the app renders the current form values as JSON. When the form is valid, we can click *Save* and the app renders the current form values as JSON.
This proves that any user input is bound back to the data model. This proves that any user input is bound back to the data model.
Saving and retrieving the data is an exercise for another time. Saving and retrieving the data is an exercise for another time.
在表单的验证通过之前,*保存*按钮是禁用的。当表单验证通过后,我们可以点击*保存*程序会把当前的值渲染成为Json。它证明了任何用户输入都被传到了数据模型。如何储存和提取数据是另一个问题。
:marked :marked
The final form looks like this: The final form looks like this:
完整表单看起来是这样:
figure.image-display figure.image-display
img(src="/resources/images/cookbooks/dynamic-form/dynamic-form.png" alt="Dynamic-Form") img(src="/resources/images/cookbooks/dynamic-form/dynamic-form.png" alt="Dynamic-Form")
:marked :marked
[Back to top](#top) [Back to top](#top)
[回到顶部](#top)

View File

@ -183,7 +183,7 @@ include _util-fns
to a [View](#view) and handling most of the views display to a [View](#view) and handling most of the views display
and user-interaction logic. and user-interaction logic.
组件是一个用来在[视图](#view)中显示数据并处理几乎所有视图显示以及用户交互逻辑的Angular类Angular Class 组件是一个用来展示数据到[视图](#view)并处理几乎所有视图显示以及用户交互逻辑的Angular类Angular Class
The Component is one of the most important building blocks in the Angular system. 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). It is, in fact, an Angular [Directive](#directive) with a companion [Template](#template).
@ -233,7 +233,7 @@ include _util-fns
Applications display data values to a user and respond to user Applications display data values to a user and respond to user
actions (clicks, touches, keystrokes). actions (clicks, touches, keystrokes).
应用程序一般将数据示给用户,并对用户的操作(点击、触屏、按键)做出回应。 应用程序一般将数据示给用户,并对用户的操作(点击、触屏、按键)做出回应。
We could push application data values into HTML, attach We could push application data values into HTML, attach
event listeners, pull changed values from the screen, and event listeners, pull changed values from the screen, and
@ -289,7 +289,7 @@ include _util-fns
Decorators are a JavaScript language [feature](https://github.com/wycats/javascript-decorators), implemented in TypeScript and proposed for ES2016 (AKA ES7). Decorators are a JavaScript language [feature](https://github.com/wycats/javascript-decorators), implemented in TypeScript and proposed for ES2016 (AKA ES7).
装饰器是一个Javascript的语言[特性](https://github.com/wycats/javascript-decorators)装饰器在TypeScript里面已经采纳并实施了它也被推荐到ES2016也就是ES7 装饰器是一个Javascript的语言[特征](https://github.com/wycats/javascript-decorators)装饰器在TypeScript里面已经采用并实施了它也被推荐到ES2016也就是ES7
We apply a decorator by positioning it We apply a decorator by positioning it
immediately above or to the left of the thing it decorates. immediately above or to the left of the thing it decorates.
@ -460,7 +460,7 @@ include _util-fns
1. [Structural Directives](#structural-directive), a directive responsible for 1. [Structural Directives](#structural-directive), a directive responsible for
shaping or re-shaping HTML layout, typically by adding, removing, or manipulating shaping or re-shaping HTML layout, typically by adding, removing, or manipulating
elements and their children. elements and their children.
[结构型指](#structural-directive)负责塑造或重塑HTML布局。一般都是通过添加、删除或者操作HTML元素和他的子级元素来实现的。 [结构型指](#structural-directive)负责塑造或重塑HTML布局。一般都是通过添加、删除或者操作HTML元素和他的子级元素来实现的。
// #enddocregion d2 // #enddocregion d2
// #docregion e1 // #docregion e1
@ -612,15 +612,22 @@ include _util-fns
[Directives](#directive) and [Components](#component) have a lifecycle [Directives](#directive) and [Components](#component) have a lifecycle
managed by Angular as it creates, updates and destroys them. managed by Angular as it creates, updates and destroys them.
[指令Directives](#directive)和[组件Components](#component)有生命周期由Angular在新建、更新和销毁的过程中管理。 [指令Directives](#directive)和[组件Components](#component)有生命周期由Angular在新建、更新和销毁他们的过程中管理。
Developers can tap into key moments in that lifecycle by implementing Developers can tap into key moments in that lifecycle by implementing
one or more of the "Lifecycle Hook" interfaces. one or more of the "Lifecycle Hook" interfaces.
开发者可以通过实现一个或多个“生命周期钩子”接口,切入到这个生命周期的关键时间点中。
Each interface has a single hook method whose name is the interface name prefixed with `ng`. Each interface has a single hook method whose name is the interface name prefixed with `ng`.
For example, the `OnInit` interface has a hook method names `ngOnInit`. For example, the `OnInit` interface has a hook method names `ngOnInit`.
每个接口有一个唯一的钩子函数方法方法,它的名字一般是接口的名字加前缀 `ng`。比如,`OnInit`接口的钩子函数方法方法名字为 `ngOnInit`。
Angular calls these hook methods in the following order: Angular calls these hook methods in the following order:
Angular会按照下面的顺序调用钩子函数方法
* `ngOnChanges` - called when an [input](#input)/[output](#output) binding values change * `ngOnChanges` - called when an [input](#input)/[output](#output) binding values change
* `ngOnInit` - after the first `ngOnChanges` * `ngOnInit` - after the first `ngOnChanges`
* `ngDoCheck` - developer's custom change detection * `ngDoCheck` - developer's custom change detection
@ -630,7 +637,18 @@ include _util-fns
* `ngAfterViewChecked` - after every check of a component's view(s) * `ngAfterViewChecked` - after every check of a component's view(s)
* `ngOnDestroy` - just before the directive is destroyed. * `ngOnDestroy` - just before the directive is destroyed.
* `ngOnChanges` - 在[输入input](#input)/[输出output](#output)绑定的值变化的时候调用。
* `ngOnInit` - 在第一个`ngOnChanges`后调用。
* `ngDoCheck` - 开发者自定义变化监测器。
* `ngAfterContentInit` - 在组件初始化以后调用。
* `ngAfterContentChecked` - 在检查每个组件内容后调用。
* `ngAfterViewInit` - 在组件试图初始化后调用。
* `ngAfterViewChecked` - 在检查每个组件试图后调用
* `ngOnDestroy` - 在指令销毁前调用。
Learn more in the [Lifecycle Hooks](guide/lifecycle-hooks.html) chapter. Learn more in the [Lifecycle Hooks](guide/lifecycle-hooks.html) chapter.
请看[生命周期钩子Lifecycle Hooks](guide/lifecycle-hooks.html)章节。
// #enddocregion f-l // #enddocregion f-l
// #docregion m1 // #docregion m1
@ -640,38 +658,60 @@ include _util-fns
.l-main-section .l-main-section
:marked :marked
## Module ## Module
## 模块
.l-sub-section .l-sub-section
:marked :marked
Angular apps are modular. Angular apps are modular.
Angular应用程序是模块化的。
In general, we assemble our application from many modules, both the ones we write ourselves In general, we assemble our application from many modules, both the ones we write ourselves
and the ones we acquire from others. and the ones we acquire from others.
一般来说,我们用模块来组装我们的应用程序,这些模块包含我们自己编写的模块和从其他地方获取的模块。
A typical module is a cohesive block of code dedicated to a single purpose. A typical module is a cohesive block of code dedicated to a single purpose.
一个典型的模块,是单一用途的代码块的凝聚。
A module **exports** something of value in that code, typically one thing such as a class. A module **exports** something of value in that code, typically one thing such as a class.
A module that needs that thing, **imports** it. A module that needs that thing, **imports** it.
模块一般**输出**一个东西:类。
模块如果需要什么东西,那就**导入**它。
The structure of Angular modules and the import/export syntax The structure of Angular modules and the import/export syntax
is based on the [ES2015](#es2015) module standard is based on the [ES2015](#es2015) module standard
described [here](http://www.2ality.com/2014/09/es6-modules-final.html). described [here](http://www.2ality.com/2014/09/es6-modules-final.html).
Angular的模块结构和输出/导入语法是基于[ES2015](#es2015)模块标准上的,请看[这里](http://www.2ality.com/2014/09/es6-modules-final.html).
An application that adheres to this standard requires a module loader to An application that adheres to this standard requires a module loader to
load modules on request and resolve inter-module dependencies. load modules on request and resolve inter-module dependencies.
Angular does not ship with a module loader and does not have a preference Angular does not ship with a module loader and does not have a preference
for any particular 3rd party library (although most samples use SystemJS). for any particular 3rd party library (although most samples use SystemJS).
Application developers may pick any module library that conforms to the standard Application developers may pick any module library that conforms to the standard
采取这个标准的应用程序需要一个模块装载器来按需装载模块并解析模块的依赖关系。Angular不包含任何模块装载器也不推荐任何第三方库(虽然几乎所有例子都使用SystemJs)。
应用程序开发者可以自己选择任何与这个标准兼容的模块装置库。
Modules are typically named after the file in which the exported thing is defined. Modules are typically named after the file in which the exported thing is defined.
The Angular [DatePipe](https://github.com/angular/angular/blob/master/modules/angular2/src/common/pipes/date_pipe.ts) The Angular [DatePipe](https://github.com/angular/angular/blob/master/modules/angular2/src/common/pipes/date_pipe.ts)
class belongs to a feature module named `date_pipe` in the file `date_pipe.ts`. class belongs to a feature module named `date_pipe` in the file `date_pipe.ts`.
模块一般与他输出的东西的所在文件同名。比如, Angular的[日期管道DatePipe](https://github.com/angular/angular/blob/master/modules/angular2/src/common/pipes/date_pipe.ts)类属于名叫`date_pipe`的特性模块,在文件`date_pipe.ts`里。
Developers rarely access Angular feature modules directly. Developers rarely access Angular feature modules directly.
We usually import them from public-facing **library modules** We usually import them from public-facing **library modules**
called [**barrels**](#barrel). Barrels are groups of logically related modules. called [**barrels**](#barrel). Barrels are groups of logically related modules.
The `angular2/core` barrel is a good example. The `angular2/core` barrel is a good example.
开发者很少需要直接访问Angular的特性模块。我们通常从名为[**封装桶**](#barrel)的公共**模块库**里面导入他们。封装通是有逻辑关联的模块的集合。封装通`angular2/core`是一个很好的例子。
Learn more in "[Modules, barrels and bundles](https://github.com/angular/angular/blob/master/modules/angular2/docs/bundles/overview.md)". Learn more in "[Modules, barrels and bundles](https://github.com/angular/angular/blob/master/modules/angular2/docs/bundles/overview.md)".
更多信息请看"[模块、封装桶和捆绑包](https://github.com/angular/angular/blob/master/modules/angular2/docs/bundles/overview.md)".
// #enddocregion m2 // #enddocregion m2
// #docregion n-s // #docregion n-s
@ -683,6 +723,7 @@ include _util-fns
.l-main-section .l-main-section
:marked :marked
## Output ## Output
## 输出
.l-sub-section .l-sub-section
:marked :marked
A directive property that can be the ***target*** of an A directive property that can be the ***target*** of an
@ -690,22 +731,34 @@ include _util-fns
Events stream *out* of this property to the receiver identified Events stream *out* of this property to the receiver identified
in the template expression to the right of the equal sign. in the template expression to the right of the equal sign.
输出Output是一个指令属性它可以一个[事件绑定Event Binding](guide/template-syntax.html#property-binding)的**标靶**。
事件流可以通过指令属性,流到接收者(模板表达式等号的右边就是接收者)
See the [Template Syntax](guide/template-syntax.html#inputs-outputs) chapter. See the [Template Syntax](guide/template-syntax.html#inputs-outputs) chapter.
请看[模板语法Template Syntax](guide/template-syntax.html#inputs-outputs)章节。
.l-main-section .l-main-section
<a id="P"></a> <a id="P"></a>
:marked :marked
## PascalCase ## PascalCase
## 帕斯卡命名法
.l-sub-section .l-sub-section
:marked :marked
The practice of writing compound words or phrases such that each word or abbreviation begins with a capital letter. The practice of writing compound words or phrases such that each word or abbreviation begins with a capital letter.
Class names are typically spelled in PascalCase. Examples include: `Person` and `Customer`. Class names are typically spelled in PascalCase. Examples include: `Person` and `Customer`.
按照每一个单词都是以大写开头的规则的编写复合词或短语的命名方法叫做帕斯卡命名法。类的名字一般都采用帕斯卡命名法。比如`Person`和`Customer`
This form is also known as **upper camel case**, to distinguish it from **lower camel case** which we simply call [camelCase](#camelcase). This form is also known as **upper camel case**, to distinguish it from **lower camel case** which we simply call [camelCase](#camelcase).
In this documentation, "PascalCase" means *upper camel case* and "camelCase" means *lower camel case*. In this documentation, "PascalCase" means *upper camel case* and "camelCase" means *lower camel case*.
这种命名法也被叫做**大驼峰式命名法**,便于与**小驼峰式命名法”或[驼峰式命名法camelCase](#camelCase)。
在本教程中,“帕斯卡命名法”都是指的*大驼峰式命名法”,“驼峰式命名法”指的都是“小驼峰式命名法”
:marked :marked
## Pipe ## Pipe
## 管道
.l-sub-section .l-sub-section
:marked :marked
An Angular pipe is a function that transforms input values to output values for An Angular pipe is a function that transforms input values to output values for
@ -713,32 +766,48 @@ include _util-fns
to associate the pipe function with a name. We then can use that to associate the pipe function with a name. We then can use that
name in our HTML to declaratively transform values on screen. name in our HTML to declaratively transform values on screen.
Angular的管道是一个函数用来把输入值转变为输出值给视图 [view](#view)。我们使用 `#{atSym}Pipe` !{decorator}来把管道函数链接到它的名字上。
然后我们可以在HTML中使用它的名字来用声明的形式在显示时把输入值转变输出值。
Here's an example that uses the built-in `currency` pipe to display Here's an example that uses the built-in `currency` pipe to display
a numeric value in the local currency. a numeric value in the local currency.
下面是一个使用内建`货币`管道来把数字值显示为本地货币的例子。
code-example(language="html" escape="html"). code-example(language="html" escape="html").
<label>Price: </label>{{product.price | currency}} <label>Price: </label>{{product.price | currency}}
:marked :marked
Learn more in the chapter on [pipes](guide/pipes.html) . Learn more in the chapter on [pipes](guide/pipes.html) .
到[管道pipes](guide/pipes.html)章节获取更多。
:marked :marked
## Provider ## Provider
## 提供者
.l-sub-section .l-sub-section
:marked :marked
A Provider creates a new instance of a dependency for the Dependency Injection system. A Provider creates a new instance of a dependency for the Dependency Injection system.
It relates a lookup token to code - sometimes called a "recipe" - that can create a dependency value. It relates a lookup token to code - sometimes called a "recipe" - that can create a dependency value.
提供者为依赖注入系统新建一个依赖的实例。它是关于通过令牌查询代码,有时被叫做“方剂”,可以创建依赖值。
For example, `new Provider(Foo, {useClass: Foo})` creates a `Provider` For example, `new Provider(Foo, {useClass: Foo})` creates a `Provider`
that relates the `Foo` token to a function that creates a new instance of the `Foo` class. that relates the `Foo` token to a function that creates a new instance of the `Foo` class.
比如,`new Provider(Foo, {useClass: Foo})`新建一个`提供者`,把`Foo`令牌联系到一个函数,这个函数新建一个`Foo`类的实例。
There are other ways to create tokens and recipes. There are other ways to create tokens and recipes.
See [Dependency Injection](#dependency-injection) chapter to learn more. See [Dependency Injection](#dependency-injection) chapter to learn more.
还有其他一些方法建立令牌和方剂。
请看[依赖注入Dependency Injection](#dependency-injection)以获取更多信息。
.l-main-section .l-main-section
<a id="Q"></a> <a id="Q"></a>
<a id="R"></a> <a id="R"></a>
:marked :marked
## Router ## Router
## 路由器
.l-sub-section .l-sub-section
:marked :marked
Most applications consist of many screens or [views](#view). Most applications consist of many screens or [views](#view).
@ -746,34 +815,54 @@ include _util-fns
and taking other similar actions that cause the application to and taking other similar actions that cause the application to
replace one view with another. replace one view with another.
大部分应用程序包含多个屏或视图[views](#view)。用户通过点击链接、按钮和其他类似动作,在他们之间穿梭,这样应用程序从一个视图变换到另一个视图。
The Angular [Component Router](guide/router.html) is a richly featured mechanism for configuring The Angular [Component Router](guide/router.html) is a richly featured mechanism for configuring
and managing the entire view navigation process including the creation and destruction and managing the entire view navigation process including the creation and destruction
of views. of views.
Angular的[组件路由器Component Router](guide/router.html)是一个设置和管理整个视图导航过程的特征非常丰富的机制,包括建立和销毁视图。
:marked :marked
## Routing Component ## Routing Component
## 路由组件
.l-sub-section .l-sub-section
:marked :marked
A [Component](#component) with an attached router. A [Component](#component) with an attached router.
路由组件是一个附加了路由的[组件Component](#component)。
In most cases, the component became attached to a [router](#router) by means In most cases, the component became attached to a [router](#router) by means
of a `#{atSym}RouterConfig` #{decorator} that defined routes to views controlled by this component. of a `#{atSym}RouterConfig` #{decorator} that defined routes to views controlled by this component.
在大部分情况下,通过`#{atSym}RouterConfig` #{decorator}装饰器,这个组件通常会被附加一个[router路由器](#router),来定义被这个组件控制的多个视图的路径。
The component's template has a `RouterOutlet` element where it can display views produced by the router. The component's template has a `RouterOutlet` element where it can display views produced by the router.
组件的模板有一个`路由出口RouterOutlet`元素,用来显示被路由器提供的视图。
It likely has anchor tags or buttons with `RouterLink` directives that users can click to navigate. It likely has anchor tags or buttons with `RouterLink` directives that users can click to navigate.
它很大可能还会有一些有`RouterLink`指令的锚标记或按钮,用户可以用来点击导航。
<a id="S"></a> <a id="S"></a>
.l-main-section .l-main-section
:marked :marked
## Structural Directive ## Structural Directive
## 结构型指令
.l-sub-section .l-sub-section
:marked :marked
A category of [Directive](#directive) that can A category of [Directive](#directive) that can
shape or re-shape HTML layout, typically by adding, removing, or manipulating shape or re-shape HTML layout, typically by adding, removing, or manipulating
elements and their children. elements and their children.
一类可以通过添加、删除或操作元素和其子级来塑造或重塑HTML布局的指令
The `ngIf` "conditional element" directive and the `ngFor` "repeater" directive are The `ngIf` "conditional element" directive and the `ngFor` "repeater" directive are
good examples in this category. good examples in this category.
`ngIf`"有条件的元素conditional element"指令和 `ngFor` "中继器repeater"指令是很好的结构型指令。
// #enddocregion n-s // #enddocregion n-s
// #docregion t1 // #docregion t1
@ -781,31 +870,40 @@ include _util-fns
.l-main-section .l-main-section
:marked :marked
## Template ## Template
## 模板
.l-sub-section .l-sub-section
:marked :marked
A template is a chunk of HTML that Angular uses to render a [view](#view) with A template is a chunk of HTML that Angular uses to render a [view](#view) with
the support and continuing guidance of an Angular [Directive](#directive), the support and continuing guidance of an Angular [Directive](#directive),
most notably a [Component](#component). most notably a [Component](#component).
模板是一块HTML。在Angular指令最典型的 指令[组件Component](#component)的支持和范围下Angular用它来渲染试图。
We write templates in a special [Template Syntax](guide/template-syntax.html). We write templates in a special [Template Syntax](guide/template-syntax.html).
我们使用特殊的[模板语法Template Syntax](guide/template-syntax.html)来编写模板。
:marked :marked
## Template Expression ## Template Expression
## 模板表达式
.l-sub-section .l-sub-section
:marked :marked
An expression in a JavaScript-like syntax that Angular evaluates within An expression in a JavaScript-like syntax that Angular evaluates within
a [data binding](#data-binding). Learn how to write template expressions a [data binding](#data-binding). Learn how to write template expressions
in the [Template Syntax](guide/template-syntax.html#template-expressions) chapter. in the [Template Syntax](guide/template-syntax.html#template-expressions) chapter.
Angular在[数据绑定data binding](#data-binding)内评估的类似Javascript语法的表达式。在[模板语法Template Syntax](guide/template-syntax.html#template-expressions)章节了解更多模板表达式的知识。
// #enddocregion t1 // #enddocregion t1
// #docregion t2 // #docregion t2
:marked :marked
## Transpile ## Transpile
## 编译
.l-sub-section .l-sub-section
:marked :marked
The process of transforming code written in one form of JavaScript The process of transforming code written in one form of JavaScript
(e.g., TypeScript) into another form of JavaScript (e.g., [ES5](#es5)). (e.g., TypeScript) into another form of JavaScript (e.g., [ES5](#es5)).
把用Javascript形式语言比如TypeScript编写的程序转换到另一个形式的JavaScript例如[ES5](#es5))。
:marked :marked
## TypeScript ## TypeScript
.l-sub-section .l-sub-section
@ -814,17 +912,28 @@ include _util-fns
language features and many features that may arrive in future versions language features and many features that may arrive in future versions
of JavaScript such as [Decorators](#decorator). of JavaScript such as [Decorators](#decorator).
一个支持几乎所有[ECMAScript 2015](#ecmascript=2015)语言特性和一些将来版本可能有的特性(比如装饰器[Decorators](#decorator)的JavaScript语言。
TypeScript is also noteable for its optional typing system which gives TypeScript is also noteable for its optional typing system which gives
us compile-time type-checking and strong tooling support (e.g. "intellisense", us compile-time type-checking and strong tooling support (e.g. "intellisense",
code completion, refactoring, and intelligent search). Many code editors code completion, refactoring, and intelligent search). Many code editors
and IDEs support TypeScript either natively or with plugins. and IDEs support TypeScript either natively or with plugins.
TypeScript同时也以其可选的类型系统出名。该类型系统给我们提供编译时间类型检查和强大的工具支持比如“Intellisense” 自动代码补齐重构和智能搜索等。许多程序编辑器和开发环境自带TypeScript支持或者通过插件支持。
TypeScript is the preferred language for Angular 2 development although TypeScript is the preferred language for Angular 2 development although
we are welcome to write in other JavaScript dialects such as [ES5](#es5). we are welcome to write in other JavaScript dialects such as [ES5](#es5).
TypeScript是Angular 2推荐使用的语言当然我们也欢迎使用其他JavaScript语言比如[ES5](#es5)。
Angular 2 itself is written in TypeScript. Angular 2 itself is written in TypeScript.
Angular 2自身是用TypeScript编写的。
Learn more about TypeScript on its [website](http://www.typescriptlang.org/). Learn more about TypeScript on its [website](http://www.typescriptlang.org/).
在TypeScript[官方网站](http://www.typescriptlang.org/)了解更多情况。
// #enddocregion t2 // #enddocregion t2
// #docregion u-z // #docregion u-z
@ -833,45 +942,64 @@ include _util-fns
.l-main-section .l-main-section
:marked :marked
## View ## View
## 视图
.l-sub-section .l-sub-section
:marked :marked
A view is a portion of the screen that displays information and responds A view is a portion of the screen that displays information and responds
to user actions such as clicks, mouse moves, and keystrokes. to user actions such as clicks, mouse moves, and keystrokes.
视图是屏幕的一块用于显示信息并回应用户动作,比如点击、移动鼠标和按键等。
Angular renders a view under the control of one or more [Directives](#directive), Angular renders a view under the control of one or more [Directives](#directive),
especially [Component](#component) directives and their companion [Templates](#template). especially [Component](#component) directives and their companion [Templates](#template).
The Component plays such a prominent role that we often The Component plays such a prominent role that we often
find it convenient to refer to a component as a view. find it convenient to refer to a component as a view.
Angular在一个或多个[指令](#directive)的控制下渲染视图,尤其是[组件](#component)指令和它配带的[模板](#template)。
组件扮演非常突出的角色,我们甚至经常为了方便,把组件代替视图来提及。
Views often contain other views and any view might be loaded and unloaded Views often contain other views and any view might be loaded and unloaded
dynamically as the user navigates through the application, typically dynamically as the user navigates through the application, typically
under the control of a [router](#router). under the control of a [router](#router).
视图一般包含其他视图,任何视图在用户在应用程序中导航的时候,可能被动态加载或卸载,一般[路由器](#router)的控制下进行。
.l-main-section .l-main-section
<a id="W"></a> <a id="W"></a>
<a id="X"></a> <a id="X"></a>
<a id="Y"></a> <a id="Y"></a>
<a id="Z"></a> <a id="Z"></a>
:marked :marked
## Zone ## Zones
## 区域
.l-sub-section .l-sub-section
:marked :marked
Zones are a mechanism for encapsulating and intercepting Zones are a mechanism for encapsulating and intercepting
a JavaScript application's asynchronous activity. a JavaScript application's asynchronous activity.
区域是一个封装和截听JavaScript应用程序异步动作的机制。
The browser DOM and JavaScript have a limited number The browser DOM and JavaScript have a limited number
of asynchronous activities, activities such as DOM events (e.g., clicks), of asynchronous activities, activities such as DOM events (e.g., clicks),
[promises](#promise), and [promises](#promise), and
[XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) [XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
calls to remote servers. calls to remote servers.
浏览器DOM和JavaScript之间有一些有限数量的异步活动比如Dom事件比如点击、[契约promises](#promise)、和[XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)查询远程服务等。
Zones intercept all of these activities and give a "zone client" the opportunity Zones intercept all of these activities and give a "zone client" the opportunity
to take action before and after the async activity completes. to take action before and after the async activity completes.
区域能截听所有这些活动,并给“区域客户端”机会在异步活动完成之前和之后采取行动。
Angular runs our application in a zone where it can respond to Angular runs our application in a zone where it can respond to
asynchronous events by checking for data changes and updating asynchronous events by checking for data changes and updating
the information it displays via [data binding](#data-binding). the information it displays via [data binding](#data-binding).
Angular在一个区域内运行我们的应用程序在这个区域内它可以对异步事件做出反应通过检查数据变化、利用数据绑定[data binding](#data-binding)更新信息显示。
Learn more about zones in this Learn more about zones in this
[Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U). [Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U).
在这里学习 [Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U)更多关于区域的知识。
// #enddocregion u-z // #enddocregion u-z