review all "我们" keyword, making the translations more natural.

This commit is contained in:
Rex 2016-06-20 10:59:00 +01:00
parent 52c118ef8a
commit 77cdd8bde8
6 changed files with 174 additions and 174 deletions

View File

@ -122,7 +122,7 @@ table(width="100%")
:marked
To filter output in our templates in Angular 1, we use the pipe character (|) and one or more filters.
要在Angular 1中过滤输出我们使用管道字符(|)以及一个或多个过滤器。
要在Angular 1中过滤输出使用管道字符(|)以及一个或多个过滤器。
In this example, we filter the `title` property to uppercase.
@ -140,7 +140,7 @@ table(width="100%")
Many (but not all) of the built-in filters from Angular 1 are
built-in pipes in Angular 2.
在Angular 2中我们使用相似的语法 —— 用管道字符(|)来过滤输出,但是我们现在直接把它叫做**管道**了。
在Angular 2中我们使用相似的语法 —— 用管道字符(|)来过滤输出,但是现在直接把它叫做**管道**了。
很多(但不是所有)Angular 1中的内建过滤器也成了Angular 2中的内建管道。
See the heading [Filters / Pipes](#Pipes) below for more information.
@ -218,7 +218,7 @@ table(width="100%")
many applications bootstrap declaratively with the `ng-app` directive,
giving it the name of the application's module (`movieHunter`).
虽然我们可以从代码中引导Angular 1应用
虽然可以从代码中引导Angular 1应用
但很多应用都是通过`ng-app`指令进行声明式引导的,只要给它一个应用模块的名字(`movieHunter`)就可以了。
td
@ -262,7 +262,7 @@ table(width="100%")
We can specify multiple classes as shown in the second example.
就像第二个例子中展示的,我们可以指定多个CSS类。
就像第二个例子中展示的可以指定多个CSS类。
td
:marked
@ -281,7 +281,7 @@ table(width="100%")
We can specify multiple classes as shown in the second example.
就像第二个例子中所展示的那样,我们可以同时指定多个类。
就像第二个例子中所展示的那样,可以同时指定多个类。
Angular 2 also has **class binding**, which is a good way to add or remove a single class
as shown in the third example.
@ -302,7 +302,7 @@ table(width="100%")
:marked
In Angular 1, the `ng-click` directive allows us to specify custom behavior when an element is clicked.
在Angular 1中`ng-click`指令能让我们指定当元素被点击时的自定义行为。
在Angular 1中`ng-click`指令指定当元素被点击时的自定义行为。
In the first example, when the button is clicked, the `toggleImage()` method in the controller referenced by the `vm` `controller as` alias is executed.
@ -325,14 +325,14 @@ table(width="100%")
Rather, we define one-way binding from the template view to the component using **event binding**.
Angular 1基于事件的指令在Angular 2中已经不存在了。
不过,我们可以使用**事件绑定**来定义从模板视图到组件的单向数据绑定。
不过,可以使用**事件绑定**来定义从模板视图到组件的单向数据绑定。
For event binding, we define the name of the target event within parenthesis and
specify a template statement in quotes to the right of the equals. Angular 2 then
sets up an event handler for the target event. When the event is raised, the handler
executes the template statement.
要使用事件绑定,我们把目标事件的名字放在圆括号中,并且使用等号右侧引号中的模板语句对它赋值。
要使用事件绑定,把目标事件的名字放在圆括号中,并且使用等号右侧引号中的模板语句对它赋值。
然后Angular 2为这个目标时间设置事件处理器。当事件被触发时这个处理器就会执行模板语句。
In the first example, when the button is clicked, the `toggleImage()` method in the associated component is executed.
@ -403,7 +403,7 @@ table(width="100%")
In Angular 2, we use property binding; there is no built-in *hide* directive.
See [ng-show](#ng-show) for more information.
在Angular 2中并没有一个内建的*hide*指令,我们可以改用属性绑定。
在Angular 2中并没有一个内建的*hide*指令,可以改用属性绑定。
参见[ng-show](#ng-show)了解更多。
tr(style=top)
@ -441,7 +441,7 @@ table(width="100%")
In Angular 2, we use property binding; there is no built-in *href* directive.
We place the element's `href` property in square brackets and set it to a quoted template expression.
在Angular 2中并没有内建的*href*指令,我们改用属性绑定。
在Angular 2中并没有内建的*href*指令,改用属性绑定。
我们把元素的`href`属性放在方括号中,并把它设成一个引号中的模板表达式。
For more information on property binding see [Template Syntax](../guide/template-syntax.html#property-binding).
@ -593,8 +593,8 @@ table(width="100%")
In Angular 2, we use property binding; there is no built-in *show* directive.
For hiding and showing elements, we bind to the HTML `hidden` property.
在Angular 2中并没有内建的*show*指令,我们可以改用属性绑定。
要隐藏或显示一个元素,我们绑定到它的`hidden`属性就可以了。
在Angular 2中并没有内建的*show*指令,可以改用属性绑定。
要隐藏或显示一个元素,绑定到它的`hidden`属性就可以了。
To conditionally display an element, place the element's `hidden` property in square brackets and
set it to a quoted template expression that evaluates to the *opposite* of *show*.
@ -633,8 +633,8 @@ table(width="100%")
In Angular 2, we use property binding; there is no built-in *src* directive.
We place the `src` property in square brackets and set it to a quoted template expression.
在Angular 2中并没有一个内建的*src*指令,我们可以使用属性绑定。
我们把`src`属性放到方括号中,并且把它设为一个引号中的绑定表达式。
在Angular 2中并没有一个内建的*src*指令,可以使用属性绑定。
把`src`属性放到方括号中,并且把它设为一个引号中的绑定表达式。
For more information on property binding see [Template Syntax](../guide/template-syntax.html#property-binding).
@ -733,9 +733,9 @@ table(width="100%")
If that method returns `true`, we see "Excellent choice!".
If that methods returns `false`, we see "No movie, sorry!".
在这个例子中,如果`favoriteHero`没有设置,则`ngSwitch`的值是`null`并且我们会看到
在这个例子中,如果`favoriteHero`没有设置,则`ngSwitch`的值是`null`,我们会看到
`*ngSwitchDefault`中的段落“Please enter ...”。
如果`favoriteHero`被设置了,它就会通过调用一个组件方法来检查他是否电影中的英雄。
如果`favoriteHero`被设置了,它就会通过调用一个组件方法来检查电影英雄。
如果该方法返回`true`我们就会看到“Excellent choice!”。
如果该方法返回`false`我们就会看到“No movie, sorry!”。
@ -763,7 +763,7 @@ a(id="filters-pipes")
Many of the built-in filters in Angular 1 have corresponding pipes in Angular 2.
For more information on pipes see [Pipes](../guide/pipes.html).
Angular 2中的**管道**为我们的模板提供了格式化和数据转换功能类似于Angular 1中的**过滤器**。
Angular 2中的**管道**为模板提供了格式化和数据转换功能类似于Angular 1中的**过滤器**。
Angular 1中的很多内建过滤器在Angular 2中都有对应的管道。
要了解管道的更多信息,参见[Pipes](../guide/pipes.html)。
@ -882,7 +882,7 @@ table(width="100%")
`SlicePipe`做同样的事,但是*两个参数的顺序是相反的*以便于JavaScript中的`slice`方法保持一致。
第一个参数是起始索引号,第二个参数是限制的数量。
和Angular 1中一样如果们改用组件中的代码实现此操作,性能将会提升。
和Angular 1中一样如果们改用组件中的代码实现此操作性能将会提升。
tr(style=top)
td
@ -1000,7 +1000,7 @@ table(width="100%")
In Angular 1, we often defined an immediately invoked function expression (or IIFE) around our controller code.
This kept our controller code out of the global namespace.
在Angular 1中我们通常会定义一个立即调用的函数表达式(IIFE)来包裹我们的控制器代码。
在Angular 1中我们通常会定义一个立即调用的函数表达式(IIFE)来包裹控制器代码。
这样让控制器代码不会污染全局命名空间。
td
@ -1010,7 +1010,7 @@ table(width="100%")
We don't need to worry about this in Angular 2 because we use ES 2015 modules
and modules handle the namespacing for us.
在Angular 2中我们不用担心这个问题因为我们使用ES 2015的模块模块会替我们处理命名空间问题。
在Angular 2中我们不用担心这个问题因为使用ES 2015的模块模块会替我们处理命名空间问题。
For more information on modules see [Architecture Overview](../guide/architecture.html#module).
@ -1030,7 +1030,7 @@ table(width="100%")
controllers, services, and other code. The second argument defines the list
of other modules that this module depends upon.
在Angular 1中我们定义一个Angular模块它将对我们的控制器、服务和其他代码进行跟踪。第二个参数定义该模块依赖的其它模块列表。
在Angular 1中我们定义一个Angular模块它将对控制器、服务和其他代码进行跟踪。第二个参数定义该模块依赖的其它模块列表。
td
:marked
@ -1045,7 +1045,7 @@ table(width="100%")
We `import` what we need from the module files.
我们`import`任何我们想从模块文件中得到的东西。
我们`import`任何想从模块文件中得到的东西。
For more information on modules see [Architecture Overview](../guide/architecture.html#module).
@ -1068,7 +1068,7 @@ table(width="100%")
In Angular 1, we have code in each controller that looks up an appropriate Angular module
and registers the controller with that module.
在Angular 1中我们在每个控制器中都有一些代码用于找到合适的Angular模块并把该控制器注册进去。
在Angular 1中在每个控制器中都有一些代码用于找到合适的Angular模块并把该控制器注册进去。
The first argument is the controller name. The second argument defines the string names of
all dependencies injected into this controller, and a reference to the controller function.
@ -1092,7 +1092,7 @@ table(width="100%")
This is how we associate a template with code, which is defined in the component class.
这就是我们把模板关联到代码的方式,它定义在组件类中。
这就是把模板关联到代码的方式,它定义在组件类中。
For more information on components see [Architecture Overview](../guide/architecture.html#component).
@ -1198,7 +1198,7 @@ a(id="style-sheets")
样式表美化我们的应用程序。
在Angular 1中我们为整个应用程序指定样式表。
当应用程序成长一段时间之后,应用程序中很多部分的样式会被合并,导致无法预计的后果。
在Angular 2中我们仍然会为整个应用程序定义样式不过现在我们也可以把样式表封装在特定的组件中。
在Angular 2中我们仍然会为整个应用程序定义样式不过现在也可以把样式表封装在特定的组件中。
table(width="100%")
col(width="50%")
@ -1229,7 +1229,7 @@ table(width="100%")
But we can now also encapsulate styles for our components.
在Angular2中我们可以继续在`index.html`中使用link标签来为应用程序定义样式。
但是我们也能在组件中封装样式。
但是也能在组件中封装样式。
:marked
### StyleUrls

View File

@ -12,7 +12,7 @@ include ../_util-fns
For an in-depth look at each fundamental concepts in component communication, we can find detailed description and
samples in the [Component Communication]() document.
要深入了解组件通讯的各个基本概念,我们可以在[组件通讯Component Communication]()文档中可以找到详细的描述和例子。
要深入了解组件通讯的各个基本概念,在[组件通讯Component Communication]()文档中可以找到详细的描述和例子。
<a id="toc"></a>
:marked
@ -87,7 +87,7 @@ figure.image-display
E2E test that all children were instantiated and displayed as expected:
端到端测试,用于确保所有的子组件都像我们所期待的那样被初始化并显示出来。
端到端测试,用于确保所有的子组件都像所期待的那样被初始化并显示出来。
+makeExample('cb-component-communication/e2e-spec.ts', 'parent-to-child')
@ -254,7 +254,7 @@ parent-to-child-local-var
A parent component cannot use data binding to read child properties or invoke child methods. We can do both by creating a template reference variable for the child element and then reference that variable *within the parent template* as seen in the following example.
父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但我们可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法,如下例所示。
父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法,如下例所示。
<a id="countdown-timer-example"></a>
@ -276,7 +276,7 @@ parent-to-child-local-var
We can place a local variable (`#timer`) on the tag (`<countdown-timer>`) representing the child component. That gives us a reference to the child component itself and the ability to access *any of its properties or methods* from within the parent template.
我们把本地变量(`#timer`)放到(`<countdown-timer>`)标签中,用来代表子组件。这样父组件的模板就得到了子组件的引用,于是可以在父组件的模板中访问子组件的所有属性和方法。
把本地变量(`#timer`)放到(`<countdown-timer>`)标签中,用来代表子组件。这样父组件的模板就得到了子组件的引用,于是可以在父组件的模板中访问子组件的所有属性和方法。
In this example, we wire parent buttons to the child's `start` and `stop` and use interpolation to display the child's `seconds` property.
@ -317,11 +317,11 @@ a(id="countdown-tests")
We can't use the *local variable* technique if an instance of the parent component *class* must read or write child component values or must call child component methods.
如果父组件的*类*需要读取子组件的属性值或调用子组件的方法,我们就不能使用*本地变量*方法
如果父组件的*类*需要读取子组件的属性值或调用子组件的方法,就不能使用*本地变量*方法。
When the parent component *class* requires that kind of access, we ***inject*** the child component into the parent as a *ViewChild*.
当父组件*类*需要这种访问时,我们可以把子组件作为*ViewChild****注入***到父组件里面。
当父组件*类*需要这种访问时,可以把子组件作为*ViewChild****注入***到父组件里面。
We'll illustrate this technique with the same [Countdown Timer](#countdown-timer-example) example. We won't change its appearance or behavior. The child [CountdownTimerComponent](#countdown-timer-example) is the same as well.
@ -331,7 +331,7 @@ a(id="countdown-tests")
:marked
We are switching from the *local variable* to the *ViewChild* technique solely for the purpose of demonstration.
我们由*本地变量*切换到*ViewChild*技术的唯一目的就是做示范。
由*本地变量*切换到*ViewChild*技术的唯一目的就是做示范。
:marked
Here is the parent, `CountdownViewChildParentComponent`:
@ -346,12 +346,12 @@ a(id="countdown-tests")
We import references to the `ViewChild` decorator and the `AfterViewInit` lifecycle hook.
我们需要通过`ViewChild`装饰器导入这个引用,并挂上`AfterViewInit`生命周期钩子。
需要通过`ViewChild`装饰器导入这个引用,并挂上`AfterViewInit`生命周期钩子。
We inject the child `CountdownTimerComponent` into the private `timerComponent` property
via the `@ViewChild` property decoration.
我们通过`@ViewChild`属性装饰器,将子组件`CountdownTimerComponent`注入到私有属性`timerComponent`里面。
通过`@ViewChild`属性装饰器,将子组件`CountdownTimerComponent`注入到私有属性`timerComponent`里面。
The `#timer` local variable is gone from the component metadata. Instead we bind the buttons to the parent component's own `start` and `stop` methods and present the ticking seconds in an interpolation around the parent component's `seconds` method.
@ -367,11 +367,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
### 测试
@ -422,11 +422,11 @@ a(id="countdown-tests")
:marked
Notice that we capture the `subscription` and unsubscribe when the `AstronautComponent` is destroyed. This is a memory-leak guard step. There is no actual risk in this app because the lifetime of a `AstronautComponent` is the same as the lifetime of the app itself. That *would not* always be true in a more complex application.
注意,我们通过`subscription`服务订阅任务,并在`AstronautComponent`被销毁的时候退订。这是一个用于防止内存泄漏的保护措施。实际上,在这个应用程序中并没有这个风险,因为`AstronautComponent`的生命期和应用程序的生命期一样长。但在更复杂的应用程序环境中就不一定了。
注意,通过`subscription`服务订阅任务,并在`AstronautComponent`被销毁的时候退订。这是一个用于防止内存泄漏的保护措施。实际上,在这个应用程序中并没有这个风险,因为`AstronautComponent`的生命期和应用程序的生命期一样长。但在更复杂的应用程序环境中就不一定了。
We do not add this guard to the `MissionControlComponent` because, as the parent, it controls the lifetime of the `MissionService`.
我们不需要在`MissionControlComponent`中添加这个保护措施,因为作为父组件,它控制着`MissionService`的生命期。
不需要在`MissionControlComponent`中添加这个保护措施,因为作为父组件,它控制着`MissionService`的生命期。
:marked
The *History* log demonstrates that messages travel in both directions between the parent `MissionControlComponent` and the `AstronautComponent` children, facilitated by the service:

View File

@ -9,7 +9,7 @@ include ../_util-fns
We identify those files with a URL in the `templateUrl` and `styleUrls` properties of the `@Component` metadata
as seen here:
我们的组件通常都是引用外部的模板和样式表文件。
组件通常都是引用外部的模板和样式表文件。
我们在`@Component`的元数据中通过`templateUrl`和`styleUrls`属性来标识出它们的位置:
+makeExample('cb-component-relative-paths/ts/app/some.component.ts','absolute-config')(format='.')
@ -35,7 +35,7 @@ include ../_util-fns
It would be much easier to write and maintain our application components if we could specify template and style locations
*relative* to their component class file.
如果我们能用*相对*于组件类文件的路径来指定模板和样式表的位置,那么编写和维护组件就会变得容易得多。
如果能用*相对*于组件类文件的路径来指定模板和样式表的位置,那么编写和维护组件就会变得容易得多。
*We can!*
@ -47,7 +47,7 @@ include ../_util-fns
with a suitable package loader such as `systemjs` or `webpack`.
Learn why [below](#why-default).
如果把应用构建成`commonjs`模块,并用一个合适的包加载器(比如`systemjs`或`webpack`)加载那些模块,我们就可以用相对路径。
如果把应用构建成`commonjs`模块,并用一个合适的包加载器(比如`systemjs`或`webpack`)加载那些模块,就可以用相对路径。
[在下方](#why-default)可以学到原理。
The Angular 2 CLI uses these technologies and defaults to the
@ -66,7 +66,7 @@ include ../_util-fns
Our goal is to specify template and style URLs *relative* to their component class files,
hence the term ***component-relative path***.
我们的目标把模板和样式表的URL指定为*相对*于组件类的路径,因此得名***组件相对路径***。
目标把模板和样式表的URL指定为*相对*于组件类的路径,因此得名***组件相对路径***。
The key to success is following a convention that puts related component files in well-known locations.
@ -76,8 +76,8 @@ include ../_util-fns
companion component class files.
Here we see the three files for `SomeComponent` sitting next to each other in the `app` folder.
我们建议把组件的模板和组件特有的样式表文件作为组件类文件的“兄弟”。
这里我们看到在`app`目录下依次有`SomeComponent`的三个文件。
建议把组件的模板和组件特有的样式表文件作为组件类文件的“兄弟”。
这里在`app`目录下依次有`SomeComponent`的三个文件。
.filetree
.file app
@ -90,7 +90,7 @@ include ../_util-fns
We'll have more files and folders &mdash; and greater folder depth &mdash; as our application grows.
We'll be fine as long as the component files travel together as the inseparable siblings they are.
当应用规模增长后,我们还会有更多的文件和目录,目录深度也会增加。
当应用规模增长后,还会有更多的文件和目录,目录深度也会增加。
如果组件的所有文件总是像形影不离的兄弟那样共进退,那该多好啊!
### Set the *moduleId*
@ -99,13 +99,13 @@ include ../_util-fns
Having adopted this file structure convention, we can specify locations of the template and style files
relative to the component class file simply by setting the `moduleId` property of the `@Component` metadata like this
采用这种文件结构约定,我们可以为模板和样式表文件指定相对于组件类文件的位置 —— 只要简单的在`@Component`元数据中设置`moduleId`属性就可以了,就像这样:
采用这种文件结构约定,可以为模板和样式表文件指定相对于组件类文件的位置 —— 只要简单的在`@Component`元数据中设置`moduleId`属性就可以了,就像这样:
+makeExample('cb-component-relative-paths/ts/app/some.component.ts','module-id')(format='.')
:marked
We strip the `app/` base path from the `templateUrl` and `styleUrls`. The result looks like this:
我们从`templateUrl`和`styleUrls`中把基准路径`app/`去掉了。结果是这样的:
从`templateUrl`和`styleUrls`中把基准路径`app/`去掉了。结果是这样的:
+makeExample('cb-component-relative-paths/ts/app/some.component.ts','relative-config')(format='.')
@ -173,8 +173,8 @@ a#why-default
因为如果没有开发人员的帮助,组件的位置是检测不到的。
Angular应用可能被用多种方式加载SystemJS包、CommonJS包等等。
我们可能会几种格式之一来生成模块。
我们甚至可能完全没有写成模块化代码。
用来生成模块的格式可以是任何格式
甚至可能完全没有写成模块化代码。
With this diversity of packaging and module load strategies,
it's not possible for Angular to know with certainty where these files reside at runtime.
@ -195,8 +195,8 @@ a#why-default
know that the semi-global `module.id` variable is available and contains
the absolute URL of the component class module file.
但是,*如果*我们遵循建议的指导原则,用`commonjs`格式编写模块,并使用一个*不错的*模块加载器,
然后,我们就知道,有一个可用的半全局变量`module.id`它包含组件类模块文件的绝对URL。
但是,*如果*遵循建议的指导原则,用`commonjs`格式编写模块,并使用一个*不错的*模块加载器,
我们要知道,有一个可用的半全局变量`module.id`它包含组件类模块文件的绝对URL。
That knowledge enables us to tell Angular where the *component* file is
by setting the `moduleId`:

View File

@ -176,7 +176,7 @@ include ../_util-fns
but (a) aren't conceptually part of the application and (b) that we could change later without
altering the essential logic of the application.
使用外部模块时如果满足下面两个条件就应该在引导过程中注册a)它在概念上不是我们程序的一部分,以及 b)将来我们可能要在不改变主要应用逻辑的情况下更换它。
使用外部模块时如果满足下面两个条件就应该在引导过程中注册a)它在概念上不是程序的一部分,以及 b)将来可能要在不改变主要应用逻辑的情况下更换它。
For example, we might configure the Component Router with different
[location strategies](../guide/router.html#location-strategy) based on environmental factors.
@ -189,12 +189,12 @@ include ../_util-fns
We'll switch to the real backend in production.
The application shouldn't know or care one way or the other.
在开发过程中可以偷偷把一个假的带样本数据的HTTP后端嵌入进来以代替对一个远程服务器(可能还不存在)进行http查询。我们在产品发布时再切换到真正的后端。应用程序不用知道也不用管正在跟哪个后端打交道。
在开发过程中可以偷偷把一个假的带样本数据的HTTP后端嵌入进来以代替对一个远程服务器(可能还不存在)进行http查询。在产品发布时再切换到真正的后端。应用程序不用知道也不用管正在跟哪个后端打交道。
See both examples in the following `main.ts`
where we list their service providers in an array in the second parameter of the `bootstrap` method.
在下面`main.ts`的两个例子中,在`bootstrap`方法的第二个数组型参数中,我们列出了它们的服务供应商。
在下面`main.ts`的两个例子中,在`bootstrap`方法的第二个数组型参数中,列出了它们的服务供应商。
+makeExample('cb-dependency-injection/ts/app/main.ts','bootstrap','app/main.ts')(format='.')
@ -286,7 +286,7 @@ figure.image-display
Although we recommend applying `@Injectable` to all service classes, do not feel bound by it.
Some developers prefer to add it only where needed and that's a reasonable policy too.
虽然我们推荐在所有服务中使用`@Injectable()`,但你也不需要一定要这么做。一些开发者就更喜欢在真正需要的地方才添加,这也是一个合理的策略。
虽然推荐在所有服务中使用`@Injectable()`,但你也不需要一定要这么做。一些开发者就更喜欢在真正需要的地方才添加,这也是一个合理的策略。
.l-sub-section
:marked
@ -328,7 +328,7 @@ figure.image-display
That isn't always desirable.
Sometimes we want to restrict service availability to a particular region of the application.
但这不一定总是我们想要的。有时候我们想要把服务的有效性限制到应用程序的一个特定区域。
但这不一定总是想要的。有时候我们想要把服务的有效性限制到应用程序的一个特定区域。
We can limit the scope of an injected service to a *branch* of the application hierarchy
by providing that service *at the sub-root component for that branch*.
@ -347,7 +347,7 @@ figure.image-display
We could also provide the `HeroService` to a *different* component elsewhere in the application.
That would result in a *different* instance of the service, living in a *different* injector.
我们也可以在应用程序别处的*不同的*组件里提供`HeroService`。这样就会导致在*不同*注入器中存在该服务的*不同*实例。
也可以在应用程序别处的*不同的*组件里提供`HeroService`。这样就会导致在*不同*注入器中存在该服务的*不同*实例。
.l-sub-section
:marked
@ -378,7 +378,7 @@ figure.image-display
Sometimes we want multiple instances of a service at *the same level of the component hierarchy*.
在*同一个级别的组件树*里,我们有时需要一个服务的多个实例。
在*同一个级别的组件树*里,有时需要一个服务的多个实例。
A good example is a service that holds state for its companion component instance.
We need a separate instance of the service for each component.
@ -386,7 +386,7 @@ figure.image-display
We call this *sandboxing* because each service and component instance has its own sandbox to play in.
一个用来保存其伴生组件的实例状态的服务就是个好例子。
每个组件,我们都需要该服务的单独实例。
每个组件都需要该服务的单独实例。
每个服务有自己的工作状态,与其它组件的服务和状态隔离。我们称作*沙盒化*,因为每个服务和组件实例都在自己的沙盒里运行。
<a id="hero-bios-component"></a>
@ -453,8 +453,8 @@ a(id="qualify-dependency-lookup")
used individually or together.
大部分时候,我们确实*想要*这个行为。
但是有时候,我们需要限制这个(依赖)查找逻辑,且/或提供一个缺失的依赖。
单独或联合使用`@Host`和`@Optional`限定型装饰器,我们就可以修改Angular的查找行为。
但是有时候,需要限制这个(依赖)查找逻辑,且/或提供一个缺失的依赖。
单独或联合使用`@Host`和`@Optional`限定型装饰器就可以修改Angular的查找行为。
The `@Optional` decorator tells Angular to continue when it can't find the dependency.
Angular sets the injection parameter to `null` instead.
@ -476,7 +476,7 @@ a(id="qualify-dependency-lookup")
The `HeroBiosAndContactsComponent` is a revision of the `HeroBiosComponent` that we looked at [above](#hero-bios-component).
`HeroBiosAndContactsComponent`是[前面](#hero-bios-component)我们见过的`HeroBiosComponent`的修改版。
`HeroBiosAndContactsComponent`是[前面](#hero-bios-component)见过的`HeroBiosComponent`的修改版。
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','hero-bios-and-contacts','app/hero-bios.component.ts (HeroBiosAndContactsComponent)')
:marked
@ -504,7 +504,7 @@ figure.image-display
:marked
Here's the `HeroContactComponent` which demonstrates the qualifying decorators that we're talking about in this section:
下面的`HeroContactComponent`,示范了我们在本节一直在讨论的限定型装饰器(@Optional和@Host)
下面的`HeroContactComponent`,示范了在本节一直在讨论的限定型装饰器(@Optional和@Host)
+makeExample('cb-dependency-injection/ts/app/hero-contact.component.ts','component','app/hero-contact.component.ts')
:marked
@ -518,7 +518,7 @@ figure.image-display
we get a reference to the cache service from the parent `HeroBioComponent`.
Angular throws if the parent lacks that service, even if a component higher in the component tree happens to have that service.
`@Host()`函数是`heroCache`属性的装饰器,确保我们从其父组件`HeroBioComponent`得到一个缓存服务。如果该父组件不存在这个服务Angular就会抛出错误即使组件树里的再上级有某个组件拥有这个服务Angular也会抛出错误。
`@Host()`函数是`heroCache`属性的装饰器,确保从其父组件`HeroBioComponent`得到一个缓存服务。如果该父组件不存在这个服务Angular就会抛出错误即使组件树里的再上级有某个组件拥有这个服务Angular也会抛出错误。
A second `@Host()` function decorates the `loggerService` property.
We know the only `LoggerService` instance in the app is provided at the `AppComponent` level.
@ -530,7 +530,7 @@ figure.image-display
Angular would throw an error if we hadn't also decorated the property with the `@Optional()` function.
Thanks to `@Optional()`, Angular sets the `loggerService` to null and the rest of the component adapts.
如果我们没有同时使用`@Optional()`装饰器的话Angular就会抛出错误。多亏了`@Optional()`Angular把`loggerService`设置为null并继续执行组件而不会抛出错误。
如果没有同时使用`@Optional()`装饰器的话Angular就会抛出错误。多亏了`@Optional()`Angular把`loggerService`设置为null并继续执行组件而不会抛出错误。
.l-sub-section
:marked
@ -550,7 +550,7 @@ figure.image-display
until it finds the logger at the `AppComponent` level. The logger logic kicks in and the hero display updates
with the gratuitous "!!!", indicating that the logger was found.
如果我们注释掉`@Host()`装饰器Angular就会沿着注入器树往上走直到在`AppComponent`中找到该日志服务。日志服务的逻辑加入进来,更新了英雄的显示信息,这表明确实找到了日志服务。
如果注释掉`@Host()`装饰器Angular就会沿着注入器树往上走直到在`AppComponent`中找到该日志服务。日志服务的逻辑加入进来,更新了英雄的显示信息,这表明确实找到了日志服务。
figure.image-display
img(src="/resources/images/cookbooks/dependency-injection/hero-bio-contact-no-host.png" alt="Without @Host")
:marked
@ -559,7 +559,7 @@ figure.image-display
<br>
`EXCEPTION: No provider for LoggerService! (HeroContactComponent -> LoggerService)`
另一方面,如果我们恢复`@Host()`装饰器,注释掉`@Optional`,应用程序就会运行失败,因为它在宿主组件级别找不到需要的日志服务。
另一方面,如果恢复`@Host()`装饰器,注释掉`@Optional`,应用程序就会运行失败,因为它在宿主组件级别找不到需要的日志服务。
<br>
`EXCEPTION: No provider for LoggerService! (HeroContactComponent -> LoggerService)`
@ -573,7 +573,7 @@ figure.image-display
Although we strive to avoid it, many visual effects and 3rd party tools (such as jQuery)
require DOM access.
偶尔,我们可能需要访问一个组件对应的DOM元素。我们尽量避免这样做,但还是有很多视觉效果和第三方工具(比如jQuery)需要访问DOM。
偶尔可能需要访问一个组件对应的DOM元素。尽量避免这样做但还是有很多视觉效果和第三方工具(比如jQuery)需要访问DOM。
To illustrate, we've written a simplified version of the `HighlightDirective` from
the [Attribute Directives](../guide/attribute-directives.html) chapter.
@ -683,7 +683,7 @@ figure.image-display
The simple class provider is the most typical by far.
We mention the class in the `providers` array and we're done.
简单的类供应商是最典型的例子。我们只要在`providers`数值里面提到该类就可以了。
简单的类供应商是最典型的例子。只要在`providers`数值里面提到该类就可以了。
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','class-provider','app/hero-bios.component.ts (类供应商)')(format='.')
:marked
@ -696,7 +696,7 @@ figure.image-display
The `HeroOfTheMonthComponent` example demonstrates many of the alternatives and why we need them.
`HeroOfTheMonthComponent`例子示范了一些备选方案,展示了我们为什么需要它们。
`HeroOfTheMonthComponent`例子示范了一些备选方案,展示了为什么需要它们。
figure.image-display
img(src="/resources/images/cookbooks/dependency-injection/hero-of-month.png" alt="Hero of the month" width="300px")
@ -765,7 +765,7 @@ a(id='usevalue')
Obviously the title string literal is immediately available.
The `someHero` variable in this example was set earlier in the file:
一个*值-供应商*的值必须要*立即*定义。我们不能事后再定义它的值。很显然,标题字符串是立刻可用的。
一个*值-供应商*的值必须要*立即*定义。不能事后再定义它的值。很显然,标题字符串是立刻可用的。
该例中的`someHero`变量是以前在下面这个文件中定义的:
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','some-hero')
@ -802,7 +802,7 @@ a(id='useclass')
We wrote it in this long form to de-mystify the preferred short form.
第一个供应商是*展开了语法糖的*,是一个典型情况的展开。一般来说,被新建的类(`HeroService`)同时也是该供应商的注入令牌。
我们这里用完整形态来编写它,来反衬我们更喜欢的缩写形式。
这里用完整形态来编写它,来反衬我们更喜欢的缩写形式。
The second provider substitutes the `DateLoggerService` for the `LoggerService`.
The `LoggerService` is already registered at the `AppComponent` level.
@ -844,7 +844,7 @@ a(id='useexisting')
We want to shrink that API surface to just the two members exposed by the `MinimalLogger` [*class-interface*](#class-interface):
通过使用别名接口来把一个API变窄是_一个_很重要的该技巧的使用例子。我们在这里就是为了这个目的使用的别名。
想象一下如果`LoggerService`有个很大的API接口(虽然它其实只有三个方法,一个属性)我们通过使用`MinimalLogger`[*类-接口*](#class-interface)别名就能成功的把这个API接口缩小到只暴露两个成员
想象一下如果`LoggerService`有个很大的API接口(虽然它其实只有三个方法,一个属性),通过使用`MinimalLogger`[*类-接口*](#class-interface)别名就能成功的把这个API接口缩小到只暴露两个成员
+makeExample('cb-dependency-injection/ts/app/date-logger.service.ts','minimal-logger','app/date-logger.service.ts (MinimalLogger)')(format='.')
:marked
@ -938,13 +938,13 @@ a(id="tokens")
Angular dependency injection is easiest when the provider *token* is a class
that is also the type of the returned dependency object (what we usually call the *service*).
Angular依赖注入当*令牌*是类的时候是最简单的,该类同时也是返回的依赖对象的类型(我们通常直接称之为*服务*)。
Angular依赖注入当*令牌*是类的时候是最简单的,该类同时也是返回的依赖对象的类型(通常直接称之为*服务*)。
But the token doesn't have to be a class and even when it is a class,
it doesn't have to be the same type as the returned object.
That's the subject of our next section.
但令牌不一定都是类,就算它是一个类,它也不一定都返回类型相同的对象。这是我们下一节的主题。
但令牌不一定都是类,就算它是一个类,它也不一定都返回类型相同的对象。这是下一节的主题。
<a id="class-interface"></a>
### class-interface
@ -966,7 +966,7 @@ a(id="tokens")
But `LoggerService` doesn't inherit from `MinimalLogger`. *No class* inherits from it.
Instead, we use it like an interface.
我们通常从一个抽象类继承。但`LoggerService`并不继承`MinimalLogger`。*没有类*会继承它。我们只把它当接口来使用。
我们通常从一个抽象类继承。但`LoggerService`并不继承`MinimalLogger`。*没有类*会继承它。只把它当接口来使用。
Look again at the declaration for `DateLoggerService`
@ -983,13 +983,13 @@ a(id="tokens")
The key benefit of a *class-interface* is that we can get the strong-typing of an interface
and we can ***use it as a provider token*** in the same manner as a normal class.
我们称这种用法的类叫做*类-接口*。它关键的好处是:给我们提供了接口的强类型,同时,我们能像正常类一样***把它当做供应商令牌使用***。
我们称这种用法的类叫做*类-接口*。它关键的好处是:提供了接口的强类型,能像正常类一样***把它当做供应商令牌使用***。
A ***class-interface*** should define *only* the members that its consumers are allowed to call.
Such a narrowing interface helps decouple the concrete class from its consumers.
The `MinimalLogger` defines just two of the `LoggerClass` members.
***类-接口***应该*只*定义它的消费者允许调用的成员。窄的接口有助于我们解耦该类的具体实现和它的消费者。
***类-接口***应该*只*定义它的消费者允许调用的成员。窄的接口有助于解耦该类的具体实现和它的消费者。
该`MinimalLogger`只定义了两个`LoggerClass`的成员。
.l-sub-section
@ -1003,7 +1003,7 @@ a(id="tokens")
They exist only in the TypeScript design space.
They disappear after the code is transpiled to JavaScript.
我们不能把接口当做供应商的令牌因为接口不是有效的JavaScript对象。
不能把接口当做供应商的令牌因为接口不是有效的JavaScript对象。
它们只存在在TypeScript的设计空间里。它们会在被编译为JavaScript之后消失。
A provider token must be a real JavaScript object of some kind:
@ -1024,7 +1024,7 @@ a(id="tokens")
:marked
It never grows larger no matter how many members we add *as long as they are typed but not implemented*.
***只要我们不实现它***,不管我们添加多少成员,它永远不会增长大小。
***只要不实现它***,不管添加多少成员,它永远不会增长大小。
a(id='opaque-token')
:marked
@ -1048,13 +1048,13 @@ a(id='opaque-token')
We encountered them twice in the *Hero of the Month* example,
in the *title* value provider and in the *runnersUp* factory provider.
`OpaqueToken`具有这些特征。我们在*Hero of the Month*例子中遇见它们两次,一个是*title*的值,一个是*runnersUp* 工厂供应商。
`OpaqueToken`具有这些特征。在*Hero of the Month*例子中遇见它们两次,一个是*title*的值,一个是*runnersUp* 工厂供应商。
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','provide-opaque-token')(format='.')
:marked
We created the `TITLE` token like this:
我们这样创建`TITLE`令牌:
这样创建`TITLE`令牌:
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','opaque-token')(format='.')
@ -1071,7 +1071,7 @@ a(id="di-inheritance")
we must re-provide and re-inject them in the derived class
and then pass them down to the base class through the constructor.
当编写一个继承自另一个组件的组件时,我们要格外小心。如果基础组件有依赖注入,我们必须要在派生类中重新提供和重新注入它们,并将它们通过构造函数传给基类。
当编写一个继承自另一个组件的组件时,要格外小心。如果基础组件有依赖注入,必须要在派生类中重新提供和重新注入它们,并将它们通过构造函数传给基类。
In this contrived example, `SortedHeroesComponent` inherits from `HeroesBaseComponent`
to display a *sorted* list of heroes.
@ -1094,7 +1094,7 @@ figure.image-display
This rule makes the component safe to construct under test without fear that it will do something dramatic like talk to the server.
That's why we call the `HeroService` from within the `ngOnInit` rather than the constructor.
我们强烈推荐简单的构造函数。它们应该***只***用来初始化变量。这个规则会帮助我们在测试环境中放心的构造组件,以免在构造它们时,无意做了一些非常戏剧化的动作(比如连接服务)。
强烈推荐简单的构造函数。它们应该***只***用来初始化变量。这个规则会帮助我们在测试环境中放心的构造组件,以免在构造它们时,无意做了一些非常戏剧化的动作(比如连接服务)。
这就是为什么我们要在`ngOnInit`里面调用`HeroService`,而不是在构造函数中。
We explain the mysterious `afterGetHeroes` below.
@ -1115,7 +1115,7 @@ figure.image-display
We must provide the `HeroService` again for *this* component,
then pass it down to the base class inside the constructor.
可惜Angular不能直接在基类里直接注入`HeroService`。我们必须在*这个*组件里再次提供`HeroService`,然后通过构造函数传给基类。
可惜Angular不能直接在基类里直接注入`HeroService`。必须在*这个*组件里再次提供`HeroService`,然后通过构造函数传给基类。
+makeExample('cb-dependency-injection/ts/app/sorted-heroes.component.ts','sorted-heroes','app/sorted-heroes.component.ts (SortedHeroesComponent)')
:marked
@ -1126,7 +1126,7 @@ figure.image-display
现在,请注意`_afterGetHeroes`方法。
我们第一反应是在`SortedHeroesComponent`组件里面建一个`ngOnInit`方法来做排序。但是Angular会先调用*派生*类的`ngOnInit`,后调用基类的`ngOnInit`
所以我们可能在*英雄到达之前*就开始排序。这就产生了一个讨厌的错误。
所以可能在*英雄到达之前*就开始排序。这就产生了一个讨厌的错误。
Overriding the base class's `afterGetHeroes` method solves the problem
@ -1166,7 +1166,7 @@ a(id="find-parent")
But because every component instance is added to an injector's container,
we can use Angular dependency injection to reach a parent component.
但没有公开的API来获取父组件的引用。但是因为每个组件的实例都被加到了依赖注入器的容器中我们可以使用Angular依赖注入来找到父组件。
但没有公开的API来获取父组件的引用。但是因为每个组件的实例都被加到了依赖注入器的容器中可以使用Angular依赖注入来找到父组件。
This section describes some techniques for doing that.
@ -1209,7 +1209,7 @@ a(id='alex')
What if we do *not* know the concrete parent component class?
如果我们*不*知道具体的父组件类名怎么办?
如果*不*知道具体的父组件类名怎么办?
A re-usable component might be a child of multiple components.
Imagine a component for rendering breaking news about a financial instrument.
@ -1222,7 +1222,7 @@ a(id='alex')
If we're lucky, they all implement the same base class
whose API our `NewsComponent` understands.
该应用程序可能有多于一打的金融工具组件。如果幸运它们可能会从同一个基类派生其API是我们的`NewsComponent`组件所能理解的。
该应用程序可能有多于一打的金融工具组件。如果幸运它们可能会从同一个基类派生其API是`NewsComponent`组件所能理解的。
.l-sub-section
:marked
@ -1236,7 +1236,7 @@ a(id='alex')
We're not claiming this is good design.
We are asking *can a component inject its parent via the parent's base class*?
这并不是好的设计。我们的问题是*一个组件是否能通过它父组件的基类来注入它的父组件呢*
这并不是好的设计。问题是*一个组件是否能通过它父组件的基类来注入它的父组件呢*
The sample's `CraigComponent` explores this question. [Looking back](#alex)
we see that the `Alex` component *extends* (*inherits*) from a class named `Base`.
@ -1257,7 +1257,7 @@ a(id='alex')
*We cannot inject a parent by its base class.*
可惜这样不行。[在线例子](/resources/live-examples/cb-dependency-injection/ts/plnkr.html)显示`alex`参数是null。
*我们不能通过基类注入父组件*。
*不能通过基类注入父组件*。
<a id="class-interface-parent"></a>
### Find a parent by its class-interface
@ -1266,7 +1266,7 @@ a(id='alex')
We can find a parent component with a [class-interface](#class-interface).
我们可以通过[类-接口](#class-interface)找到一个父组件。
可以通过[类-接口](#class-interface)找到一个父组件。
The parent must cooperate by providing an *alias* to itself in the name of a *class-interface* token.
@ -1275,7 +1275,7 @@ a(id='alex')
Recall that Angular always adds a component instance to its own injector;
that's why we could inject *Alex* into *Carol* [earlier](#known-parent).
请记住Angular总是从它自己的注入器添加一个组件实例这就是为什么在[之前](#known-parent)我们可以*Alex*注入到*Carol*。
请记住Angular总是从它自己的注入器添加一个组件实例这就是为什么在[之前](#known-parent)可以*Alex*注入到*Carol*。
We write an [*alias provider*](#useexisting) &mdash; a `provide` object literal with a `useExisting` definition &mdash;
that creates an *alternative* way to inject the same component instance
@ -1290,11 +1290,11 @@ a(id="alex-providers")
[Parent](#parent-token) is the provider's *class-interface* token.
The [*forwardRef*](#forwardref) breaks the circular reference we just created by having the `AlexComponent` refer to itself.
[Parent](#parent-token)是该供应商的*类-接口*令牌。`AlexComponent`引用了自身,造成循环引用,我们使用[*forwardRef*](#forwardRef)打破了该循环。
[Parent](#parent-token)是该供应商的*类-接口*令牌。`AlexComponent`引用了自身,造成循环引用,使用[*forwardRef*](#forwardRef)打破了该循环。
*Carol*, the third of *Alex*'s child components, injects the parent into its `parent` parameter, the same way we've done it before:
*Carol**Alex*的第三个子组件,把父级注入到了自己的`parent`参数,和我们之前做的一样:
*Carol**Alex*的第三个子组件,把父级注入到了自己的`parent`参数,和之前做的一样:
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','carol-class','parent-finder.component.ts (CarolComponent class)')(format='.')
:marked
@ -1332,7 +1332,7 @@ a(id="parent-tree")
If we're going to keep writing [*alias providers*](#useexisting) like this we should create a [helper function](#provideparent).
*Barry*的`providers`数组看起来很像[*Alex*的那个](#alex-providers).
如果我们准备一直像这样编写[*别名供应商*](#useexisting)的话,我们应该建立一个[帮助函数](#provideparent)。
如果准备一直像这样编写[*别名供应商*](#useexisting)的话,我们应该建立一个[帮助函数](#provideparent)。
For now, focus on *Barry*'s constructor:
@ -1359,7 +1359,7 @@ a(id="parent-tree")
2. Angular throws a cyclic dependency error if we omit the `@SkipSelf` decorator.
2. 如果我们没写`@SkipSelf`装饰器的话Angular就会抛出一个循环依赖错误。
2. 如果没写`@SkipSelf`装饰器的话Angular就会抛出一个循环依赖错误。
`Cannot instantiate cyclic dependency! (BethComponent -> Parent -> BethComponent)`
@ -1430,20 +1430,20 @@ a(id="provideparent")
:marked
We can extract that logic into a helper function like this:
我们可以像这样把该逻辑抽取到一个助手函数里:
可以像这样把该逻辑抽取到一个助手函数里:
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','provide-the-parent')(format='.')
:marked
Now we can add a simpler, more meaningful parent provider to our components:
现在就可以为我们的组件添加一个更简单、直观的父级供应商了:
现在就可以为组件添加一个更简单、直观的父级供应商了:
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alice-providers')(format='.')
:marked
We can do better. The current version of the helper function can only alias the `Parent` *class-interface*.
Our application might have a variety of parent types, each with its own *class-interface* token.
我们可以做得更好。当前版本的助手函数只能为`Parent`*类-接口*提供别名。我们的应用程序可能有很多类型的父组件,每个父组件有自己的*类-接口*令牌。
我们可以做得更好。当前版本的助手函数只能为`Parent`*类-接口*提供别名。应用程序可能有很多类型的父组件,每个父组件有自己的*类-接口*令牌。
Here's a revised version that defaults to `parent` but also accepts an optional second parameter for a different parent *class-interface*.
@ -1453,7 +1453,7 @@ a(id="provideparent")
:marked
And here's how we could use it with a different parent type:
下面的代码演示了我们要如何使它添加一个不同类型的父级:
下面的代码演示了如何使它添加一个不同类型的父级:
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','beth-providers')(format='.')
:marked
@ -1468,7 +1468,7 @@ a(id="forwardref")
The order of class declaration matters in TypeScript.
We can't refer directly to a class until it's been defined.
在TypeScript里面类声明的顺序是很重要的。如果一个类尚未定义我们就不能引用它。
在TypeScript里面类声明的顺序是很重要的。如果一个类尚未定义就不能引用它。
This isn't usually a problem, especially if we adhere to the recommended *one class per file* rule.
But sometimes circular references are unavoidable.
@ -1484,7 +1484,7 @@ a(id="forwardref")
The *Parent Finder* sample is full of circular class references that are impossible to break.
这个*父组件查找器*例子里,到处都是我们无法打破的类循环引用。
这个*父组件查找器*例子里,到处都是无法打破的类循环引用。
In the [*Alex/Cathy* example](#known-parent) above:
@ -1502,7 +1502,7 @@ a(id="forwardref")
*Alex* refers to *Cathy* and *Cathy* refers to *Alex*. We're stuck. We must define one of them first.
*Alex* 引用了*Cathy*,同时,*Cathy*引用了*Alex*。我们被卡住了。我们必须要先定义它们中的一个。
*Alex* 引用了*Cathy*,同时,*Cathy*引用了*Alex*。我们被卡住了。必须要先定义它们中的一个。
We defined *Alex* first and built its `C_DIRECTIVES` array with a forward reference to *Cathy*:
@ -1521,7 +1521,7 @@ a(id="forwardref")
while we can add `forwardRef(CathyComponent)` to *Alex*'s `directives` array,
we can't write `public alex: forwardRef(AlexComponent))` in *Cathy*'s constructor.
我们*只能*先定义*Alex*,因为我们可以添加`forwardRef(CathyComponent)`到*Alex*的`Directives`数组里面,但是我们不能在*Cathy*的构造函数里面使用`public alex: forwardRef(AlexComponent))`。
*只能*先定义*Alex*,因为我们可以添加`forwardRef(CathyComponent)`到*Alex*的`Directives`数组里面,但是不能在*Cathy*的构造函数里面使用`public alex: forwardRef(AlexComponent))`。
:marked
We face a similar dilemma when a class makes *a reference to itself*

View File

@ -93,7 +93,7 @@ include _util-fns
:marked
We can add a barrel to the `heroes` folder (called `index` by convention) that exports all of these items:
我们可以在`heroes`目录下添加一个封装桶(按规约叫做`index`),它导出所有这三条:
在`heroes`目录下添加一个封装桶(按规约叫做`index`),它导出所有这三条:
code-example(format='').
export * from './hero.model.ts'; // re-export all of its exports
export * from './hero.service.ts'; // re-export all of its exports
@ -112,7 +112,7 @@ include _util-fns
:marked
That's why we can write this:
这就是为什么我们可以这样写的原因:
这就是为什么可以这样写的原因:
+makeExample('../docs/_fragments/quickstart/ts/app/app.component.ts', 'import')(format=".")
// #docregion b-c
@ -143,7 +143,7 @@ include _util-fns
and optionally registers service [providers](#provider) with the
[dependency injection system](#dependency-injection).
我们通过一个名叫`bootstrap`的方法来引导Angular应用程序。这个`bootstrap`方法会识别应用程序的顶级“根”[组件(Component)](#component)
通过一个名叫`bootstrap`的方法来引导Angular应用程序。这个`bootstrap`方法会识别应用程序的顶级“根”[组件(Component)](#component)
并可能通过[依赖注入体系(Dependency Injection System)](#dependency-injection)注册服务的[供应商(Provider)](#provider)。
One can bootstrap multiple apps in the same `index.html`, each with its own top level root.
@ -169,8 +169,8 @@ include _util-fns
This form is also known as **lower camel case**, to distinguish it from **upper camel case** which we call [PascalCase](#pascalcase).
When we write "camelCase" in this documentation we always mean *lower camel case*.
这种形式也被叫做**小驼峰式命名法(lower camel case)**,以区分于**大驼峰式命名法**(我们也叫[Pascal命名法(PascalCase)](#pascalcase))。
当我们在文档中提到“驼峰式命名法(camelCase)”的时候,所指的都是小驼峰命名法。
这种形式也被叫做**小驼峰式命名法(lower camel case)**,以区分于**大驼峰式命名法**(也叫[Pascal命名法(PascalCase)](#pascalcase))。
在文档中提到“驼峰式命名法(camelCase)”的时候,我们所指的都是小驼峰命名法。
:marked
## Component
@ -237,13 +237,13 @@ include _util-fns
event listeners, pull changed values from the screen, and
update application data values ... all by hand.
我们当然也可以自己处理这些操作将数据显示到HTML网页添加事件监听器从屏幕获取数据变化然后更新数据等等……
当然也可以自己处理这些操作将数据显示到HTML网页添加事件监听器从屏幕获取数据变化然后更新数据等等……
Or we could declare the relationship between an HTML widget
and an application data source ... and let a data binding
framework handle the details.
或者,我们也可以声明HTML小部件和数据源的关系……让一个数据绑定框架来处理所有细节。
或者也可以声明HTML小部件和数据源的关系……让一个数据绑定框架来处理所有细节。
Data Binding is that second approach. Angular has a rich
data binding framework with a variety of data binding
@ -291,7 +291,7 @@ include _util-fns
We apply a decorator by positioning it
immediately above or to the left of the thing it decorates.
我们应用装饰器的方法是把装饰器放到被装饰对象的上面或左边。
应用装饰器的方法是把装饰器放到被装饰对象的上面或左边。
Angular has its own set of decorators to help it interoperate with our application parts.
Here is an example of a `@Component` decorator that identifies a
@ -348,14 +348,14 @@ include _util-fns
part "A" relies on another part "B", we say that "A" depends on "B" and
that "B" is a dependency of "A".
这些小部件通常会依赖其它小部件。一个Angular[组件(Component)](#component)可能依赖一个“服务”部件来获取数据或处理运算。当部件A要靠另一个部件B才能工作我们就说A“依赖于”BB是A的“依赖”。
这些小部件通常会依赖其它小部件。一个Angular[组件(Component)](#component)可能依赖一个“服务”部件来获取数据或处理运算。如果部件A要靠另一个部件B才能工作那么A“依赖于”BB是A的“依赖”。
We can ask a "Dependency Injection System" to create "A"
for us and handle all the dependencies.
If "A" needs "B" and "B" needs "C", the system resolves that chain of dependencies
and returns a fully prepared instance of "A".
我们可以要求“依赖注入系统”为我们创建一个部件A并处理所有A的“依赖”。如果A需要BB需要C这个系统便解析这个依赖链给我们返回一个完全准备好的A实例。
我们可以要求“依赖注入系统”为我们创建一个部件A并处理所有A的“依赖”。如果A需要BB需要C这个系统便解析这个依赖链返回一个完全准备好的A实例。
Angular provides and relies upon its own sophisticated
[Dependency Injection](dependency-injection.html) system
@ -375,7 +375,7 @@ include _util-fns
the value associated with the token for the `Foo` class, typically an instance of `Foo` itself.
令牌是一个Angular中的类型(`OpaqueToken`)。我们很少需要直接接触令牌。绝大多数类方法都接受类名(`Foo`)或字符串("foo")Angular会把这些类名称和字符串转换成令牌。
我们调用`injector.get(Foo)`时,注入器返回用`Foo`类生成的令牌所对应的依赖值,该依赖值通常是`Foo`类的实例。
当调用`injector.get(Foo)`时,注入器返回用`Foo`类生成的令牌所对应的依赖值,该依赖值通常是`Foo`类的实例。
Angular makes similar requests internally during many of its operations
as when it creates a [`Component`](#AppComponent) for display.
@ -664,7 +664,7 @@ include _util-fns
In general, we assemble our application from many modules, both the ones we write ourselves
and the ones we acquire from others.
一般来说,我们用模块来组装我们的应用程序,这些模块包含我们自己编写的模块和从其它地方获取的模块。
一般来说,我们用模块来组装应用程序,这些模块包含我们自己编写的模块和从其它地方获取的模块。
A typical module is a cohesive block of code dedicated to a single purpose.
@ -758,8 +758,8 @@ include _util-fns
to associate the pipe function with a name. We then can use that
name in our HTML to declaratively transform values on screen.
Angular的管道是一个函数用于把输入值转换成输出值以供[视图(View)](#view)显示。我们使用`#{atSym}Pipe`!{decoratorCn}来把管道函数关联到它的名字上。
然后,我们就可以在HTML中用它的名字来声明该如何把输入值转换为显示值了。
Angular的管道是一个函数用于把输入值转换成输出值以供[视图(View)](#view)显示。使用`#{atSym}Pipe`!{decoratorCn}来把管道函数关联到它的名字上。
然后就可以在HTML中用它的名字来声明该如何把输入值转换为显示值了。
Here's an example that uses the built-in `currency` pipe to display
a numeric value in the local currency.
@ -859,7 +859,7 @@ include _util-fns
The only difference, from a consumer perspective,
is that the package name begins with the Angular *scope name*, `@angular`.
我们使用和导入*普通*包相同的方式导入范围化包。
使用和导入*普通*包相同的方式导入范围化包。
从消费者的视角看唯一的不同是那些包的名字是用Angular的*范围名*`@angular`开头儿的。
+makeExample('../docs/_fragments/architecture/ts/app/app.component.ts', 'import')(format=".")
@ -899,7 +899,7 @@ include _util-fns
We write templates in a special [Template Syntax](/docs/ts/latest/guide/template-syntax.html).
我们使用特殊的[模板语法](/docs/ts/latest/guide/template-syntax.html)来编写模板。
使用特殊的[模板语法](/docs/ts/latest/guide/template-syntax.html)来编写模板。
:marked
## Template Expression
@ -937,7 +937,7 @@ include _util-fns
code completion, refactoring, and intelligent search). Many code editors
and IDEs support TypeScript either natively or with plugins.
TypeScript还以它的可选类型系统而著称。该类型系统给我们提供了编译期类型检查和强大的工具支持(比如“Intellisense” 自动代码补齐,重构和智能搜索等)。许多程序编辑器和开发环境都自带了TypeScript支持或通过插件提供支持。
TypeScript还以它的可选类型系统而著称。该类型系统提供了编译期类型检查和强大的工具支持(比如“Intellisense” 自动代码补齐,重构和智能搜索等)。许多程序编辑器和开发环境都自带了TypeScript支持或通过插件提供支持。
TypeScript is the preferred language for Angular 2 development although
we are welcome to write in other JavaScript dialects such as [ES5](#es5).
@ -974,7 +974,7 @@ include _util-fns
find it convenient to refer to a component as a view.
Angular在一个或多个[指令(Directive)](#directive)的控制下渲染视图,尤其是[组件(Component)](#component)型指令及其[模板(Template)](#template)。
组件扮演着非常重要的角色,甚至我们经常会为了方便而直接用“视图”作为组件的代名词。
组件扮演着非常重要的角色,我们甚至经常会为了方便, 直接用“视图”作为组件的代名词。
Views often contain other views and any view might be loaded and unloaded
dynamically as the user navigates through the application, typically
@ -1015,7 +1015,7 @@ include _util-fns
asynchronous events by checking for data changes and updating
the information it displays via [data binding](#data-binding).
Angular会在一个区域中运行我们的应用程序,在这个区域中,它可以对异步事件做出反应,可以通过检查数据变更、利用[数据绑定(Data Binding)](#data-binding)来更新信息显示。
Angular会在一个 Zone 区域中运行应用程序,在这个区域中,它可以对异步事件做出反应,可以通过检查数据变更、利用[数据绑定(Data Binding)](#data-binding)来更新信息显示。
Learn more about zones in this
[Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U).

View File

@ -94,7 +94,7 @@ block download-source
[download the QuickStart source](https://github.com/angular/quickstart/blob/master/README.md)
from github and follow its brief instructions.
如果不想跟着这里的操作指南来一步步儿做,我们也可以从github[下载“快速起步”的源码](https://github.com/angular/quickstart/blob/master/README.md),这样只要注意那些操作要点就行了。
如果不想跟着这里的操作指南来一步步儿做可以从github[下载“快速起步”的源码](https://github.com/angular/quickstart/blob/master/README.md),这样只要注意那些操作要点就行了。
.l-main-section
button(class="verbose off md-primary md-button md-ink-ripple", type="button", onclick="verbose(false)").
@ -121,7 +121,7 @@ button(class="verbose on md-primary md-button md-ink-ripple", type="button", onc
:marked
We'll see many code blocks as we build the QuickStart app. They're all easy to copy and paste:
我们构建这个“快速起步”应用时,会看到很多代码块。它们都很方便拷贝和粘贴:
当构建这个“快速起步”应用时,我们会看到很多代码块。它们都很方便拷贝和粘贴:
code-example(format="nocode").
点击右侧的图标,来把代码片段拷贝到剪贴板 ==>
@ -205,7 +205,7 @@ block install-packages
We install the packages listed in `package.json` using `npm`. Enter the
following command in a terminal window (command window in Windows):
我们使用`npm`命令来安装`package.json`中列出的依赖包。请在终端窗口(或Windows的cmd窗口)中输入下列命令:
使用`npm`命令来安装`package.json`中列出的依赖包。请在终端窗口(或Windows的cmd窗口)中输入下列命令:
code-example(language="sh").
npm install
@ -240,7 +240,7 @@ block install-packages
If the recompile fails, the package recovers (typically with a pre-built version)
and everything works.
我们通常会在一系列`gyp ERR!`消息后面看到一个`npm WARN`消息。直接忽略即可。
通常会在一系列`gyp ERR!`消息后面看到一个`npm WARN`消息。忽略即可。
有些依赖包可能会尝试用`node-gyp`重新编译它自己。
如果重新编译失败了,这个包就会自行恢复(通常是下载一个预编译版本),最终不会影响使用。
@ -251,7 +251,7 @@ block install-packages
.l-verbose-section
:marked
#### Adding the libraries and packages we need with *npm*
#### 用*npm*添加我们需要的库和依赖包
#### 用*npm*添加需要的库和依赖包
Angular application developers rely on the _[npm](https://docs.npmjs.com)_
package manager to install the libraries and packages their apps require.
@ -267,14 +267,14 @@ block install-packages
#### 有用的脚本
We've included a number of npm scripts in our suggested `package.json` to handle common development tasks:
我们推荐的这个`package.json`中包含了几个npm脚本用来处理常用的开发任务
在推荐的这个`package.json`中包含了几个npm脚本用来处理常用的开发任务
+makeJson('quickstart/ts/package.1.json',{ paths: 'scripts'}, 'package.json (脚本)')(format=".")
:marked
We execute most npm scripts in the following way: `npm run` followed by a *script-name*.
Some commands (such as `start`) don't require the `run` keyword.
我们执行大多数npm脚本的方式都差不多`npm run`后面跟着*脚本名*。
执行大多数npm脚本的方式都差不多`npm run`后面跟着*脚本名*。
有些命令(比如`start`)不需要`run`关键字。
Here's what these scripts do:
@ -310,7 +310,7 @@ block install-packages
:marked
**We're all set.** Let's write some code.
**全部设置完了。** 我们来写点代码吧。
**全部设置完了。** 来写点代码吧。
.l-main-section
h2#root-component Step 2: Our first Angular component
@ -318,7 +318,7 @@ h2#root-component 步骤2我们的第一个Angular组件
:marked
Let's create a folder to hold our application and add a super-simple Angular component.
我们来创建一个文件夹,用于保存我们的应用并且添加一个超级简单的Angular组件。
创建一个文件夹,用于保存应用程序并且添加一个超级简单的Angular组件。
**Create #{_an} #{_appDir} subfolder** off the project root directory:
@ -353,11 +353,11 @@ p.
This QuickStart has only one, extremely simple component.
But it has the essential structure of every component we'll ever write:
这个“快速起步”只有一个非常简单的组件,但麻雀虽小,五脏俱全 —— 它具备了我们将来写的组件的基本结构。
这个“快速起步”只有一个非常简单的组件,但麻雀虽小,五脏俱全 —— 它具备了将来写的组件的基本结构。
* One or more [import](#component-import)
statements to reference the things we need.
* 一个或多个[import](#component-import)语句来引入我们所需的文件。
* 一个或多个[import](#component-import)语句来引入所需的文件。
* A [@Component #{_decorator}](#component-decorator)
that tells Angular what template to use and how to create the component.
* 一个[@Component #{_decoratorCn}](#component-decorator)
@ -377,14 +377,14 @@ p.
each made up of several, related features that we'll use to build our application.
Angular应用都是模块化的。它们由很多职责明确的文件组成。
Angular本身也是模块化的。它包括一系列的库模块这些模块包括了一系列相关的特性以便我们可以拿来构建自己的应用。
Angular本身也是模块化的。它包括一系列的库模块这些模块包括了一系列相关的特性以便拿来构建应用程序
When we need something from a module or library, we import it.
Here we import the Angular 2 core so that our component code can have access to
the `@Component` #{_decorator}.
我们需要一个模块中的某些东西时,我们引入(import)它。
在这里我们导入了Angular 2核心库以便我们的组件代码能够访问`@Component` #{_decoratorCn}。
当需要一个模块中的某些东西时,引入(import)它。
在这里我们导入了Angular 2核心库以便组件代码访问`@Component` #{_decoratorCn}。
+makeExcerpt('app/app.component.ts', 'import')
h3#component-decorator @Component #{_decorator}
@ -396,13 +396,13 @@ p.
**@** symbol and invoking it with a metadata object, just above the class.
`Component`是一个*装饰器函数*,它接受一个*元数据对象*作为参数。
通过给这个函数加上**@**前缀,我们就可以把这个函数加到组件类上,比如上面这个类。
通过给这个函数加上**@**前缀,可以把这个函数加到组件类上,比如上面这个类。
:marked
`@Component` is #{_a} *#{_decorator}* that allows us to associate *metadata* with the
component class.
The metadata tells Angular how to create and use this component.
`@Component` 是一个*#{_decoratorCn}*,它允许我们把*元数据*关联到组件类上。这些元数据会告诉Angular如何创建和使用我们的类。
`@Component` 是一个*#{_decoratorCn}*,它把*元数据*关联到组件类上。这些元数据会告诉Angular如何创建和使用组件类。
+makeExcerpt('app/app.component.ts', 'metadata')
@ -432,7 +432,7 @@ p.
>Our template is a single line of HTML announcing "*My First Angular 2 App*".
>我们的模板中只有一行HTML“*My First Angular App*”。
>模板中只有一行HTML“*My First Angular App*”。
>A more advanced template could contain data bindings to component properties
and might identify other application compoents which have their own templates.
@ -454,14 +454,14 @@ p.
we can expand this class with properties and application logic.
Our `AppComponent` class is empty because we don't need it to do anything in this QuickStart.
当我们打算构建一个真实的应用时,可以通过添加属性和应用逻辑来扩展这个类。
我们不需要在这个“快速起步”中做这些事,所以这里的`AppComponent`类是空的。
打算构建一个真实的应用时,通过添加属性和应用逻辑来扩展这个类。
但不需要在这个“快速起步”中做这些事,所以这里的`AppComponent`类是空的。
+ifDocsFor('ts')
:marked
We **export** `AppComponent` so that we can **import** it elsewhere in our application,
as we'll see when we create `main.ts`.
我们**导出**`AppComponent`,以便我们可以在应用的其它地方**导入**它 —— 比如我们创建`main.ts`时。
**导出**`AppComponent`,以便在应用的其它地方**导入**它 —— 比如创建`main.ts`时。
.l-main-section
h2#main Step 3: Add #[code #[+adjExPath('main.ts')]]
h2#main 步骤3添加#[code #[+adjExPath('main.ts')]]
@ -489,7 +489,7 @@ block create-main
Then we call `bootstrap` with `AppComponent`.
然后,我们调用`bootstrap`函数,并且把`AppComponent`传进去。
然后,调用`bootstrap`函数,并且把`AppComponent`传进去。
### Bootstrapping is platform-specific
### “启动”是平台相关的
@ -510,8 +510,8 @@ block create-main
These targets require a different kind of bootstrap function that we'd import from a different library.
但从其它环境中加载组件也是可能的。
我们可能通过[Apache Cordova](https://cordova.apache.org/) 或 [NativeScript](https://www.nativescript.org/) 在移动设备中加载它。
我们可能希望在服务器中渲染我们的第一个页面来提高启动效率或
可能需要通过[Apache Cordova](https://cordova.apache.org/) 或 [NativeScript](https://www.nativescript.org/) 在移动设备中加载它。
可能希望在服务器中渲染第一个页面来提高启动效率或
让[SEO](http://static.googleusercontent.com/media/www.google.com/en//webmasters/docs/search-engine-optimization-starter-guide.pdf)更加容易。
要达成这些目标,我们需要从其它库中引入一个不同类型的`bootstrap`函数。
@ -537,7 +537,7 @@ block create-main
但我们应该用正确的方式组织Angular应用的文件结构。
启动App与展现视图是两个相互分离的关注点。
把这些关注点混在一起会增加不必要的难度。
我们可以通过使用不同的引导器(bootstraper)来在不同的环境中启动`AppComponent`。
可以通过使用不同的引导器(bootstraper)来在不同的环境中启动`AppComponent`。
测试组件也变得更容易,因为不需要再运行整个程序才能跑测试。
让我们多花一点精力来用*“正确的方式”*实现它。
@ -568,9 +568,9 @@ h2#index 步骤4添加#[code index.html]
1. JavaScript [库](#libraries)
2. Configuration file for [SystemJS](#systemjs), and a script
where we import and run the `app` module which refers to the `main` file that we just wrote.
2. 配置[SystemJS](#systemjs),以便引入和运行我们刚才写的`main`文件。
2. 配置[SystemJS](#systemjs),以便引入和运行刚才写的`main`文件。
3. The [`<my-app>`](#my-app) tag in the `<body>` which is *where our app lives!*
3. `<body>`中的[&lt;my-app>](#my-app)标签是*供我们的应用“生活”的地方。*
3. `<body>`中的[&lt;my-app>](#my-app)标签是*供应用程序“生活”的地方。*
:marked
### Libraries
@ -584,7 +584,7 @@ h2#index 步骤4添加#[code index.html]
Next are the polyfills for Angular2, `zone.js` and `reflect-metadata`.
Then the [SystemJS](#systemjs) library for module loading.
我们首先引入es6-shim它会给全局对象window打上补丁使其支持ES2015(ES6)的必备特性。
首先引入es6-shim它会给全局对象window打上补丁使其支持ES2015(ES6)的必备特性。
然后是Angular 2的polyfills以及`zone.js`和`reflect-metadata`。
然后是用于模块加载的[SystemJS](#systemjs)库。
@ -592,7 +592,7 @@ h2#index 步骤4添加#[code index.html]
become more concerned about production qualities such as
load times and memory footprint.
等我们变得更有经验、更关心产品质量(如加载时间、内存足迹等),也可以做出不同的选择。
等我们变得更有经验、更关心产品质量(如加载时间、内存足迹等),也可以做出不同的选择。
h3#systemjs SystemJS
:marked
QuickStart uses <a href="https://github.com/systemjs/systemjs" target="_blank">SystemJS</a>
@ -606,20 +606,20 @@ h2#index 步骤4添加#[code index.html]
本“快速起步”使用<a href="https://github.com/systemjs/systemjs" target="_blank">SystemJS</a>来加载应用和库模块。
[以前](#add-config-files)我们曾把`systemjs.config.js`文件添加到项目的根目录。
还有一些其它候选者也能很好地工作,比如备受推崇的[webpack](guide/webpack.html)。
SystemJS是一个好的选择但要清楚它只是我们给你的“选择之一”,而不是“首选项”。
SystemJS是一个好的选择但要清楚它只是“选择之一”而不是“首选项”。
All module loaders require configuration and all loader configuration
becomes complicated rather quickly as soon as the file structure diversifies and
we start thinking about building for production and performance.
所有loader(模块加载器)都需要配置,并且文件结构很快就会变得多样,
loader的配置也会变得复杂那时候我们就要开始考虑产品构建和性能问题了。
loader的配置也会变得复杂那时候就要开始考虑产品构建和性能问题了。
We suggest becoming well-versed in the loader of your choice.
Learn more about SystemJS configuration
<a href="https://github.com/systemjs/systemjs/blob/master/docs/config-api.md" target="_blank">here</a>.
我们建议你要精通你所选的loader。
建议你要精通你所选的loader。
要学习如何配置SystemJS的更多知识参见<a href="https://github.com/systemjs/systemjs/blob/master/docs/config-api.md" target="_blank">这里</a>。
With those cautions in mind, what are we doing in the
@ -628,10 +628,10 @@ h2#index 步骤4添加#[code index.html]
Then, we register all our packages to SystemJS:
all the project dependencies and our application package, `app`.
把这些记在心里,我们再来看看加在“快速起步”中的[`systemjs.config.js`配置文件](#config-files)都做了什么。
把这些记在心里,再来看看加在“快速起步”中的[`systemjs.config.js`配置文件](#config-files)都做了什么。
首先创建了一个映射表来告诉SystemJS当想要引入某些模块的时候该到哪里去找。
然后,我们把自己的所有包注册到SystemJS中
项目的所有外部依赖,以及我们自己的应用包`app`。
然后把自己的所有包注册到SystemJS中
项目的所有外部依赖,以及自己的应用包`app`。
.l-sub-section
:marked
@ -653,7 +653,7 @@ h2#index 步骤4添加#[code index.html]
Our QuickStart makes such requests when one of its
application TypeScript files has an import statement like this:
我们的“快速起步”中当应用中的一个TypeScript文件有这样的一个导入语句时
在“快速起步”中当应用中的一个TypeScript文件有这样的一个导入语句时
+makeExcerpt('app/main.ts', 'import')
:marked
SystemJS就会开始介入。
@ -667,7 +667,7 @@ h2#index 步骤4添加#[code index.html]
That makes sense because we transpile TypeScript to JavaScript
*before* running the application.
这是因为我们在运行应用程序*之前*会执行从TypeScript到JavaScript的转译(transpile)。
这是因为在运行应用程序*之前*会执行从TypeScript到JavaScript的转译(transpile)。
.l-sub-section
:marked
#### Transpiling in the browser
@ -684,11 +684,11 @@ h2#index 步骤4添加#[code index.html]
We strongly recommend transpiling (AKA compiling) to JavaScript during a build phase
before running the application for several reasons including:
我们强烈建议在运行应用之前的build阶段转译(编译)到JavaScript理由包括
强烈建议在运行应用之前的build阶段转译(编译)到JavaScript理由包括
* We see compiler warnings and errors that are hidden from us in the browser.
* 我们可以看到编译器的警告和错误,但浏览器中不行。
* 可以看到编译器的警告和错误,但浏览器中不行。
* Precompilation simplifies the module loading process and
it's much easier to diagnose problems when this is a separate, external step.
@ -702,7 +702,7 @@ h2#index 步骤4添加#[code index.html]
* We iterate development faster because we only recompile changed files.
We notice the difference as soon as the app grows beyond a handful of files.
* 我们的迭代开发会更快,因为我们只需要重新编译那些有变化的文件。当应用程序快速膨胀成一大堆文件时,你会体验到这些差异。
* 迭代开发会更快,因为只需要重新编译那些有变化的文件。当应用程序快速膨胀成一大堆文件时,你会体验到这些差异。
* Precompilation fits into a continuous integration process of build, test, deploy.
@ -715,8 +715,8 @@ h2#index 步骤4添加#[code index.html]
We also catch and log launch errors to the console.
`System.import`调用告诉SystemJS引入`main`文件。(`main.js`,从`main.ts`转译而来的,还记得吧?)
`main`是我们让Angular启动应用的地方。
我们还会把启动过程中的错误捕获并记录到控制台中。
`main`是让Angular启动应用的地方。
还会把启动过程中的错误捕获并记录到控制台中。
All other modules are loaded upon request
either by an import statement or by Angular itself.
@ -732,14 +732,14 @@ h2#index 步骤4添加#[code index.html]
and renders our application's view between those tags.
当Angular在`main.ts`中调用`bootstrap`函数时,它读取`AppComponent`的元数据,
发现选择器是`my-app`,于是它定位到一个元素名为`my-app`的DOM元素并且把我们的应用加载到这个标签中。
发现选择器是`my-app`,于是它定位到一个元素名为`my-app`的DOM元素并且把应用加载到这个标签中。
:marked
### Add some style
### 添加一些样式
Styles aren't essential but they're nice, and `index.html` assumes we have
a stylesheet called `styles.css`.
样式不是必备的,但是它让我们的应用更漂亮。`index.html`假设我们有一个名叫`styles.css`的样式表。
样式不是必备的,但是它让应用更漂亮。`index.html`假设有一个名叫`styles.css`的样式表。
Create a `styles.css` file in the *#{_indexHtmlDir}* folder and start styling, perhaps with the minimal
styles shown below. For the full set of master styles used by the documentation samples,
@ -807,7 +807,7 @@ block server-watching
We close the terminal window when we're done to terminate both the compiler and the server.
当终止了编译器和服务器之后,我们可以关闭terminal窗口。
当终止了编译器和服务器之后可以关闭terminal窗口。
.l-main-section
:marked
# Wrap up
@ -864,14 +864,14 @@ block project-files
Our first application doesn't do much. It's basically "Hello, World" for Angular 2.
我们的第一个应用没做什么它只是Angular 2的“Hello, World”。
第一个应用没做什么它只是Angular 2的“Hello, World”。
We kept it simple in our first pass: we wrote a little Angular component,
created a simple `index.html`, and launched with a
static file server. That's about all we'd expect to do for a "Hello, World" app.
我们让自己的Angular 2处女航保持简单我们写了一个小的Angular组件添加一些JavaScript库到`index.html`,并且启动一个静态文件服务器。
这就是我们想通过“Hello, World”应用表现的一切。
为了让自己的Angular 2处女航保持简单我们写了一个小的Angular组件添加一些JavaScript库到`index.html`,并且启动一个静态文件服务器。
这就是通过“Hello, World”应用表现的一切。
**We have greater ambitions!**
@ -883,8 +883,8 @@ block what-next-ts-overhead
We'll likely open `index.html` only if we need to add a library or some css stylesheets.
好消息是:准备阶段(几乎)已经结束了。
我们将来可能只是修改`package.json`来升级依赖库。
如果需要添加一些库或一些css样式表我们可以打开`index.html`。
将来可能只是修改`package.json`来升级依赖库。
如果需要添加一些库或一些css样式表可以打开`index.html`。
:marked
We're about to take the next step and build a small application that
demonstrates the great things we can build with Angular 2.