Merge pull request #157 from todoubaba/displaying-data

Polish displaying-data.jade (round 2)
This commit is contained in:
Rex 2016-11-30 17:24:41 +00:00 committed by GitHub
commit 18b8e32493
1 changed files with 69 additions and 60 deletions

View File

@ -6,13 +6,14 @@ block includes
:marked :marked
You can display data by binding controls in an HTML template to properties of an Angular component. You can display data by binding controls in an HTML template to properties of an Angular component.
在Angular中最典型的数据显示方式就是把HTML模板中的控件绑定到Angular组件的属性。 Angular 中最典型的数据显示方式,就是把 HTML 模板中的控件绑定到 Angular 组件的属性。
In this page, you'll create a component with a list of heroes. In this page, you'll create a component with a list of heroes.
You'll display the list of hero names and You'll display the list of hero names and
conditionally show a message below the list. conditionally show a message below the list.
本章中,我们将创建一个英雄列表组件。我们将显示英雄名字的列表,并在列表下方显示一条消息。 本章中,你将创建一个英雄列表组件。
你将显示英雄名字的列表,并根据条件在列表下方显示一条消息。
The final UI looks like this: The final UI looks like this:
@ -23,14 +24,20 @@ figure.image-display
:marked :marked
# Contents # Contents
# 目录 # 目录
* [Showing component properties with interpolation](#interpolation) * [Showing component properties with interpolation](#interpolation)
* [通过插值表达式显示组件的属性](#interpolation)
[通过插值表达式显示组件的属性](#interpolation)
* [Showing !{_an} !{_array} property with NgFor](#ngFor) * [Showing !{_an} !{_array} property with NgFor](#ngFor)
* [通过NgFor显示数组型属性](#ngFor)
[通过 NgFor 显示数组型属性](#ngFor)
* [Conditional display with NgIf](#ngIf) * [Conditional display with NgIf](#ngIf)
* [通过NgIf实现按条件显示](#ngIf)
[通过 NgIf 实现按条件显示](#ngIf)
.l-sub-section .l-sub-section
:marked :marked
@ -42,19 +49,20 @@ figure.image-display
.l-main-section#interpolation .l-main-section#interpolation
:marked :marked
## Showing component properties with interpolation ## Showing component properties with interpolation
## 使用插值表达式显示组件属性 ## 使用插值表达式显示组件属性
The easiest way to display a component property The easiest way to display a component property
is to bind the property name through interpolation. is to bind the property name through interpolation.
With interpolation, you put the property name in the view template, enclosed in double curly braces: `{{myHero}}`. With interpolation, you put the property name in the view template, enclosed in double curly braces: `{{myHero}}`.
要显示组件的属性,最简单的方式就是通过插值表达式interpolation来绑定属性名。 要显示组件的属性,最简单的方式就是通过插值表达式 (interpolation) 来绑定属性名。
要使用插值表达式,就把属性名包裹在双花括号里放进视图模板,如`{{myHero}}`。 要使用插值表达式,就把属性名包裹在双花括号里放进视图模板,如`{{myHero}}`。
Follow the [setup](setup.html) instructions for creating a new project Follow the [setup](setup.html) instructions for creating a new project
named <ngio-ex path="displaying-data"></ngio-ex>. named <ngio-ex path="displaying-data"></ngio-ex>.
按照[搭建本地开发环境](setup.html)的说明,创建一个新项目,名为<ngio-ex path="displaying-data"></ngio-ex>。 按照[开发环境](setup.html)的说明,创建一个新项目,名为<ngio-ex path="displaying-data"></ngio-ex>。
Then modify the <ngio-ex path="app.component.ts"></ngio-ex> file by Then modify the <ngio-ex path="app.component.ts"></ngio-ex> file by
changing the template and the body of the component. changing the template and the body of the component.
@ -87,33 +95,33 @@ figure.image-display
quote (`'`)&mdash;allows you to compose a string over several lines, which makes the quote (`'`)&mdash;allows you to compose a string over several lines, which makes the
HTML more readable. HTML more readable.
模板是包在ECMAScript 2015反引号<code>\`</code>中的一个多行字符串。 模板是包在 ECMAScript 2015 反引号 (<code>\`</code>) 中的一个多行字符串。
反引号<code>\`</code> —— 注意,不是单引号(') —— 允许把一个字符串写在多行上, 反引号 (<code>\`</code>) &mdash; 注意,不是单引号 (') &mdash; 允许把一个字符串写在多行上,
使HTML模板更容易阅读。 使 HTML 模板更容易阅读。
:marked :marked
Angular automatically pulls the value of the `title` and `myHero` properties from the component and Angular automatically pulls the value of the `title` and `myHero` properties from the component and
inserts those values into the browser. Angular updates the display inserts those values into the browser. Angular updates the display
when these properties change. when these properties change.
Angular自动从组件中提取`title`和`myHero`属性的值并且把这些值插入浏览器中。当这些属性发生变化时Angular就会自动刷新显示。 Angular 自动从组件中提取`title`和`myHero`属性的值并且把这些值插入浏览器中。当这些属性发生变化时Angular 就会自动刷新显示。
.l-sub-section .l-sub-section
:marked :marked
More precisely, the redisplay occurs after some kind of asynchronous event related to More precisely, the redisplay occurs after some kind of asynchronous event related to
the view, such as a keystroke, a timer completion, or a response to an HTTP request. the view, such as a keystroke, a timer completion, or a response to an HTTP request.
严格来说,“重新显示”是在某些与视图有关的异步事件之后发生的,比如按键、定时器完成或对HTTP请求的响应。 严格来说,“重新显示”是在某些与视图有关的异步事件之后发生的,例如,按键、定时器完成或对 HTTP 请求的响应。
:marked :marked
Notice that you don't call **new** to create an instance of the `AppComponent` class. Notice that you don't call **new** to create an instance of the `AppComponent` class.
Angular is creating an instance for you. How? Angular is creating an instance for you. How?
注意,我们从没调用过**new**来创建`AppComponent`类的实例是Angular替我们创建了它。那么它是如何创建的呢? 注意,我们没有调用 **new** 来创建`AppComponent`类的实例,是 Angular 替我们创建了它。那么它是如何创建的呢?
The CSS `selector` in the `@Component` !{_decorator} specifies an element named `<my-app>`. The CSS `selector` in the `@Component` !{_decorator} specifies an element named `<my-app>`.
That element is a placeholder in the body of your `index.html` file: That element is a placeholder in the body of your `index.html` file:
注意`@Component`装饰器中指定的CSS选择器`selector`,它指定了一个叫`my-app`的元素。 注意`@Component`装饰器中指定的 CSS 选择器`selector`,它指定了一个叫`my-app`的元素。
该元素是`index.html`的`body`里的占位符。 该元素是`index.html`的`body`里的占位符。
+makeExcerpt('index.html', 'body') +makeExcerpt('index.html', 'body')
@ -123,12 +131,12 @@ figure.image-display
in the `index.html`, finds it, instantiates an instance of `AppComponent`, and renders it in the `index.html`, finds it, instantiates an instance of `AppComponent`, and renders it
inside the `<my-app>` tag. inside the `<my-app>` tag.
当我们通过`main.ts`中的`AppComponent`类启动时Angular在`index.html`中查找一个`<my-app>`元素, 当我们通过`main.ts`中的`AppComponent`类启动时Angular 在`index.html`中查找一个`<my-app>`元素,
然后实例化一个`AppComponent`,并将其渲染到`<my-app>`标签中。 然后实例化一个`AppComponent`,并将其渲染到`<my-app>`标签中。
Now run the app. It should display the title and hero name: Now run the app. It should display the title and hero name:
试一下本应用。它应该显示出标题和英雄名。 运行应用。它应该显示出标题和英雄名:
figure.image-display figure.image-display
img(src="/resources/images/devguide/displaying-data/title-and-hero.png" alt="Title and Hero") img(src="/resources/images/devguide/displaying-data/title-and-hero.png" alt="Title and Hero")
@ -137,33 +145,34 @@ figure.image-display
:marked :marked
The next few sections review some of the coding choices in the app. The next few sections review some of the coding choices in the app.
我们来回顾一下前所做的决定,看看还有哪些其它选择。 回顾一下前所做的决定,看看还有哪些其它选择。
:marked :marked
## Template inline or template file? ## Template inline or template file?
## 内联inline模板还是模板文件? ## 内联 (inline) 模板还是模板文件?
You can store your component's template in one of two places. You can store your component's template in one of two places.
You can define it *inline* using the `template` property, or you can define You can define it *inline* using the `template` property, or you can define
the template in a separate HTML file and link to it in the template in a separate HTML file and link to it in
the component metadata using the `@Component` !{_decorator}'s `templateUrl` property. the component metadata using the `@Component` !{_decorator}'s `templateUrl` property.
我们有两种地方可以用来存放组件模板。 你可以在两种地方存放组件模板。
我们可以使用`template`属性把它定义为 *内联* 的或者把模板定义在一个独立的HTML文件中 你可以使用`template`属性把它定义为*内联*的,或者把模板定义在一个独立的 HTML 文件中,
并通过在`@Component`装饰器中的`templateUrl`属性把它链接到组件。 再通过`@Component`装饰器中的`templateUrl`属性,
在组件元数据中把它链接到组件。
The choice between inline and separate HTML is a matter of taste, The choice between inline and separate HTML is a matter of taste,
circumstances, and organization policy. circumstances, and organization policy.
Here the app uses inline HTML because the template is small and the demo Here the app uses inline HTML because the template is small and the demo
is simpler without the additional HTML file. is simpler without the additional HTML file.
到底选择内联HTML还是独立HTML取决于个人喜好、具体状况和组织级策略。 到底选择内联 HTML 还是独立 HTML 取决于个人喜好、具体状况和组织级策略。
这里我们选择内联HTML是因为模板很小而且没有额外的HTML文件显得这个演示简单些。 上面的应用选择内联 HTML ,是因为模板很小,而且没有额外的 HTML 文件显得这个演示简单些。
In either style, the template data bindings have the same access to the component's properties. In either style, the template data bindings have the same access to the component's properties.
无论用哪种风格,模板中的数据绑定在访问组件属性方面都是完全一样的。 无论用哪种风格,模板数据绑定在访问组件属性方面都是完全一样的。
+ifDocsFor('ts') +ifDocsFor('ts')
:marked :marked
@ -198,7 +207,7 @@ figure.image-display
Now use the Angular `ngFor` directive in the template to display Now use the Angular `ngFor` directive in the template to display
each item in the `heroes` list. each item in the `heroes` list.
现在我们在模板中使用Angular的`ngFor`指令来显示`heroes`列表中的每一项。 接着,在模板中使用 Angular 的`ngFor`指令来显示`heroes`列表中的每一项。
+makeExcerpt('app/app.component.2.ts', 'template') +makeExcerpt('app/app.component.2.ts', 'template')
@ -207,8 +216,8 @@ figure.image-display
in the `<li>` element is the Angular "repeater" directive. in the `<li>` element is the Angular "repeater" directive.
It marks that `<li>` element (and its children) as the "repeater template": It marks that `<li>` element (and its children) as the "repeater template":
这个界面使用了由`<ul>`和`<li>`标签组成的无序列表。`<li>`元素里的`*ngFor`是Angular的“迭代”指令。 这个界面使用了由`<ul>`和`<li>`标签组成的无序列表。`<li>`元素里的`*ngFor`是 Angular 的“迭代”指令。
它将`<li>`元素和它的子级标记为“迭代模板”: 它将`<li>`元素及其子级标记为“迭代模板”:
+makeExcerpt('app/app.component.2.ts ()', 'li', '') +makeExcerpt('app/app.component.2.ts ()', 'li', '')
@ -217,8 +226,8 @@ figure.image-display
Don't forget the leading asterisk (\*) in `*ngFor`. It is an essential part of the syntax. Don't forget the leading asterisk (\*) in `*ngFor`. It is an essential part of the syntax.
For more information, see the [Template Syntax](./template-syntax.html#ngFor) page. For more information, see the [Template Syntax](./template-syntax.html#ngFor) page.
不要忘记`*ngFor`中的前导星号\*。它是语法中不可或缺的一部分。 不要忘记`*ngFor`中的前导星号 (\*)。它是语法中不可或缺的一部分。
要了解关于此语法和`ngFor`的更多知识,请参见[模板语法](./template-syntax.html#ngFor)一章 更多信息,见[模板语法](./template-syntax.html#ngFor)
:marked :marked
Notice the `hero` in the `ngFor` double-quoted instruction; Notice the `hero` in the `ngFor` double-quoted instruction;
it is an example of a template input variable. Read it is an example of a template input variable. Read
@ -227,21 +236,21 @@ figure.image-display
注意看`ngFor`双引号表达式中的`hero`,它是一个模板输入变量。 注意看`ngFor`双引号表达式中的`hero`,它是一个模板输入变量。
更多模板输入变量的信息,见[模板语法](./template-syntax.html)中的 更多模板输入变量的信息,见[模板语法](./template-syntax.html)中的
[微语法microsyntax](./template-syntax.html#ngForMicrosyntax)。 [微语法 (microsyntax)](./template-syntax.html#ngForMicrosyntax)。
Angular duplicates the `<li>` for each item in the list, setting the `hero` variable Angular duplicates the `<li>` for each item in the list, setting the `hero` variable
to the item (the hero) in the current iteration. Angular uses that variable as the to the item (the hero) in the current iteration. Angular uses that variable as the
context for the interpolation in the double curly braces. context for the interpolation in the double curly braces.
Angular为列表中的每个条目复制一个`<li>`元素,在每个迭代中,都会把`hero`变量设置为当前条目(英雄)。 Angular 为列表中的每个条目复制一个`<li>`元素,在每个迭代中,把`hero`变量设置为当前条目(英雄)。
Angular把`hero`变量作为双花括号插值表达式的上下文。 Angular 把`hero`变量作为双花括号插值表达式的上下文。
.l-sub-section .l-sub-section
:marked :marked
In this case, `ngFor` is displaying !{_an} !{_array}, but `ngFor` can In this case, `ngFor` is displaying !{_an} !{_array}, but `ngFor` can
repeat items for any [iterable](!{_iterableUrl}) object. repeat items for any [iterable](!{_iterableUrl}) object.
本例中,`ngFor`用于显示一个“数组”, 本例中,`ngFor`用于显示一个“数组”,
但`ngFor`可以为任何[可迭代的iterable](!{_iterableUrl})对象重复渲染条目。 但`ngFor`可以为任何[可迭代的 (iterable) ](!{_iterableUrl})对象重复渲染条目。
:marked :marked
Now the heroes appear in an unordered list. Now the heroes appear in an unordered list.
@ -266,7 +275,7 @@ figure.image-display
At the moment, the binding is to !{_an} !{_array} of strings. At the moment, the binding is to !{_an} !{_array} of strings.
In real applications, most bindings are to more specialized objects. In real applications, most bindings are to more specialized objects.
现在,我们绑定到了一个字符串数组。在真实的应用中,大多时候我们会绑定到一个对象数组 现在使用的是到了一个字符串数组的绑定。在真实的应用中,大多是到一个对象数组的绑定
To convert this binding to use specialized objects, turn the !{_array} To convert this binding to use specialized objects, turn the !{_array}
of hero names into !{_an} !{_array} of `Hero` objects. For that you'll need a `Hero` class. of hero names into !{_an} !{_array} of `Hero` objects. For that you'll need a `Hero` class.
@ -283,12 +292,12 @@ block hero-class
:marked :marked
You've defined a class with a constructor and two properties: `id` and `name`. You've defined a class with a constructor and two properties: `id` and `name`.
我们定义了一个类,具有一个构造函数和两个属性:`id`和`name`。 定义了一个类,具有一个构造函数和两个属性:`id`和`name`。
It might not look like the class has properties, but it does. It might not look like the class has properties, but it does.
The declaration of the constructor parameters takes advantage of a TypeScript shortcut. The declaration of the constructor parameters takes advantage of a TypeScript shortcut.
它可能看上去不像是有属性的类,但我们确实有。我们利用的是TypeScript提供的简写形式 —— 用构造函数的参数直接定义属性。 它可能看上去不像是有属性的类,但它确实有,利用的是 TypeScript 提供的简写形式 —— 用构造函数的参数直接定义属性。
Consider the first parameter: Consider the first parameter:
@ -303,26 +312,26 @@ block hero-class
* Declares a constructor parameter and its type * Declares a constructor parameter and its type
* 声明了一个构造函数参数及其类型 声明了一个构造函数参数及其类型
* Declares a public property of the same name * Declares a public property of the same name
* 声明了一个同名的公共属性 声明了一个同名的公共属性
* Initializes that property with the corresponding argument when we "new" an instance of the class * Initializes that property with the corresponding argument when we "new" an instance of the class
* 当我们`new`出该类的一个实例时,把该属性初始化为相应的参数值 当我们`new`出该类的一个实例时,把该属性初始化为相应的参数值
.l-main-section .l-main-section
:marked :marked
## Using the Hero class ## Using the Hero class
## 使用Hero类 ## 使用 Hero
The `heroes` property in the component can now use the `Hero` class to return !{_an} !{_array} The `heroes` property in the component can now use the `Hero` class to return !{_an} !{_array}
of `Hero` objects: of `Hero` objects:
我们让组件中的`heroes`属性返回一个`Hero`对象的数组。 现在使用`Hero`类,让组件中的`heroes`属性返回一个`Hero`对象的数组。
+makeExcerpt('app/app.component.3.ts', 'heroes') +makeExcerpt('app/app.component.3.ts', 'heroes')
@ -331,7 +340,7 @@ block hero-class
At the moment it displays the hero's `id` and `name`. At the moment it displays the hero's `id` and `name`.
Fix that to display only the hero's `name` property. Fix that to display only the hero's `name` property.
我们还得更新一下模板。 接着,更新一下模板。
现在它显示的是英雄的`id`和`name`。 现在它显示的是英雄的`id`和`name`。
要修复它,只显示英雄的`name`属性就行了。 要修复它,只显示英雄的`name`属性就行了。
@ -340,17 +349,17 @@ block hero-class
:marked :marked
Our display looks the same, but now we know much better what a hero really is. Our display looks the same, but now we know much better what a hero really is.
从显示上看还是一样,但现在除了名字之外,我们可以有更多英雄信息。 从显示上看还是一样,但现在我们知道了更多英雄信息。
.l-main-section#ngIf .l-main-section#ngIf
:marked :marked
## Conditional display with NgIf ## Conditional display with NgIf
## 通过NgIf进行条件显示 ## 通过 NgIf 进行条件显示
Sometimes an app needs to display a view or a portion of a view only under specific circumstances. Sometimes an app needs to display a view or a portion of a view only under specific circumstances.
有时,应用需要只在特定情况下显示视图或视图的一部分。 有时,应用需要只在特定情况下显示视图或视图的一部分。
Let's change the example to display a message if there are more than three heroes. Let's change the example to display a message if there are more than three heroes.
@ -359,8 +368,8 @@ block hero-class
The Angular `ngIf` directive inserts or removes an element based on a !{_boolean} condition. The Angular `ngIf` directive inserts or removes an element based on a !{_boolean} condition.
To see it in action, add the following paragraph at the bottom of the template: To see it in action, add the following paragraph at the bottom of the template:
Angular的`ngIf`指令会根据一个布尔条件来显示或移除一个元素。 Angular 的`ngIf`指令会根据一个布尔条件来显示或移除一个元素。
我们来亲自动手试一下,把下列语句加到模板的底部: 来看看实际效果,把下列语句加到模板的底部:
+makeExcerpt('app/app.component.ts', 'message') +makeExcerpt('app/app.component.ts', 'message')
@ -369,7 +378,7 @@ block hero-class
Don't forget the leading asterisk (\*) in `*ngIf`. It is an essential part of the syntax. Don't forget the leading asterisk (\*) in `*ngIf`. It is an essential part of the syntax.
Read more about `ngIf` and `*` in the [ngIf section](./template-syntax.html#ngIf) of the [Template Syntax](./template-syntax.html) page. Read more about `ngIf` and `*` in the [ngIf section](./template-syntax.html#ngIf) of the [Template Syntax](./template-syntax.html) page.
不要忘了`*ngIf`中的前导星号\*。它是本语法中不可或缺的一部分。 不要忘了`*ngIf`中的前导星号 (\*)。它是本语法中不可或缺的一部分。
更多`ngIf`和`* `的内容,见[模板语法](./template-syntax.html)中的[ngIf](./template-syntax.html#ngIf)。 更多`ngIf`和`* `的内容,见[模板语法](./template-syntax.html)中的[ngIf](./template-syntax.html#ngIf)。
:marked :marked
@ -381,16 +390,16 @@ block hero-class
see the [template expressions](./template-syntax.html#template-expressions) section of the see the [template expressions](./template-syntax.html#template-expressions) section of the
[Template Syntax](./template-syntax.html) page. [Template Syntax](./template-syntax.html) page.
双引号中的模板表达式`*ngIf="heros.length > 3"`,外观和行为很象!{_Lang}。 双引号中的模板表达式`*ngIf="heros.length > 3"`,外观和行为很象 !{_Lang}。
当组件中的英雄列表有三个以上的条目时Angular把这个段落添加到DOM中于是消息显示了出来。 当组件中的英雄列表有三个以上的条目时Angular 把这个段落添加到 DOM 中,于是消息显示了出来。
更多信息,见[模板语法](./template-syntax.html)中的[模板表达式](./template-syntax.html#template-expressions)。 更多信息,见[模板语法](./template-syntax.html)中的[模板表达式](./template-syntax.html#template-expressions)。
.alert.is-helpful .alert.is-helpful
:marked :marked
Angular isn't showing and hiding the message. It is adding and removing the paragraph element from the DOM. That improves performance, especially in larger projects when conditionally including or excluding Angular isn't showing and hiding the message. It is adding and removing the paragraph element from the DOM. That improves performance, especially in larger projects when conditionally including or excluding
big chunks of HTML with many data bindings. big chunks of HTML with many data bindings.
Angular并不是在显示和隐藏这条消息它是在从DOM中添加和移除这个段落元素。 Angular 并不是在显示和隐藏这条消息,它是在从 DOM 中添加和移除这个段落元素。
这会提高性能特别是在一些大的项目中有条件地包含或排除一大堆带着很多数据绑定的HTML时。 这会提高性能,特别是在一些大的项目中有条件地包含或排除一大堆带着很多数据绑定的 HTML 时。
:marked :marked
Try it out. Because the !{_array} has four items, the message should appear. Try it out. Because the !{_array} has four items, the message should appear.
@ -398,8 +407,8 @@ block hero-class
The browser should refresh automatically and the message should disappear. The browser should refresh automatically and the message should disappear.
试一下。因为这个数组中有四个条目,所以消息应该显示出来。 试一下。因为这个数组中有四个条目,所以消息应该显示出来。
回到`app.component.ts`从英雄数组中删除或注释掉一个元素。 回到`app.component.ts`,从英雄数组中删除或注释掉一个元素。
浏览器应该自动刷新,消息应该会消失。 浏览器应该自动刷新,消息应该会消失。
.l-main-section .l-main-section
:marked :marked
## Summary ## Summary
@ -408,27 +417,27 @@ block hero-class
Now you know how to use: Now you know how to use:
现在我们知道了如何使用以下内容 现在你知道了如何使用
- **Interpolation** with double curly braces to display a component property - **Interpolation** with double curly braces to display a component property
- 用带有双花括号的**插值表达式interpolation**来显示一个组件属性 带有双花括号的**插值表达式 (interpolation) **来显示一个组件属性
- **ngFor** to display !{_an} !{_array} of items - **ngFor** to display !{_an} !{_array} of items
- 用**ngFor**来显示数组 **ngFor** 来显示数组
- A !{_Lang} class to shape the **model data** for our component and display properties of that model - A !{_Lang} class to shape the **model data** for our component and display properties of that model
- 用一个!{_Lang}类来为我们的组件描述**数据模型**并显示模型的属性。 用一个 !{_Lang} 类来为我们的组件描述**模型数据**并显示模型的属性
- **ngIf** to conditionally display a chunk of HTML based on a boolean expression - **ngIf** to conditionally display a chunk of HTML based on a boolean expression
- **ngIf**用来根据一个布尔表达式有条件地显示一段HTML **ngIf** 来根据一个布尔表达式有条件地显示一段 HTML
Here's the final code: Here's the final code:
下面是我们的最终代码: 下面是最终代码:
block final-code block final-code
+makeTabs(`displaying-data/ts/app/app.component.ts, +makeTabs(`displaying-data/ts/app/app.component.ts,