# Template syntax
# 模板语法
The Angular application manages what the user sees and can do, achieving this through the interaction of a component class instance (the *component*) and its user-facing template.
Angular 应用管理着用户之所见和所为,并通过 Component 类的实例(*组件*)和面向用户的模板交互来实现这一点。
You may be familiar with the component/template duality from your experience with model-view-controller (MVC) or model-view-viewmodel (MVVM).
In Angular, the component plays the part of the controller/viewmodel, and the template represents the view.
从使用模型-视图-控制器 (MVC) 或模型-视图-视图模型 (MVVM) 的经验中,很多开发人员都熟悉了组件和模板这两个概念。
在 Angular 中,组件扮演着控制器或视图模型的角色,模板则扮演视图的角色。
This page is a comprehensive technical reference to the Angular template language.
It explains basic principles of the template language and describes most of the syntax that you'll encounter elsewhere in the documentation.
这是一篇关于 Angular 模板语言的技术大全。
它解释了模板语言的基本原理,并描述了你将在文档中其它地方遇到的大部分语法。
Many code snippets illustrate the points and concepts, all of them available
in the .
这里还有很多代码片段用来解释技术点和概念,它们全都在中。
{@a html}
## HTML in templates
## 模板中的 HTML
HTML is the language of the Angular template.
Almost all HTML syntax is valid template syntax.
The ` Syntax" is the interpolated evil title.
"Template alert("evil never sleeps")Syntax" is the property bound evil title.
{@a other-bindings}
## Attribute, class, and style bindings
## attribute、class 和 style 绑定
The template syntax provides specialized one-way bindings for scenarios less well-suited to property binding.
模板语法为那些不太适合使用属性绑定的场景提供了专门的单向数据绑定形式。
To see attribute, class, and style bindings in a functioning app, see the especially for this section.
要在运行中的应用查看 Attribute 绑定、类绑定和样式绑定,请参见 特别是对于本节。
### Attribute binding
### attribute 绑定
Set the value of an attribute directly with an **attribute binding**. This is the only exception to the rule that a binding sets a target property and the only binding that creates and sets an attribute.
可以直接使用 **Attribute 绑定**设置 Attribute 的值。一般来说,绑定时设置的是目标的 Property,而 Attribute 绑定是唯一的例外,它创建和设置的是 Attribute。
Usually, setting an element property with a [property binding](guide/template-syntax#property-binding)
is preferable to setting the attribute with a string. However, sometimes
there is no element property to bind, so attribute binding is the solution.
通常,使用 [Property 绑定](guide/template-syntax#property-binding)设置元素的 Property 优于使用字符串设置 Attribute。但是,有时没有要绑定的元素的 Property,所以其解决方案就是 Attribute 绑定。
Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). They are purely attributes, don't correspond to element properties, and don't set element properties. In these cases, there are no property targets to bind to.
考虑 [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) 和 [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG)。它们都纯粹是 Attribute,不对应于元素的 Property,也不能设置元素的 Property。
在这些情况下,就没有要绑定到的目标 Property。
Attribute binding syntax resembles property binding, but
instead of an element property between brackets, start with the prefix `attr`,
followed by a dot (`.`), and the name of the attribute.
You then set the attribute value, using an expression that resolves to a string,
or remove the attribute when the expression resolves to `null`.
Attribute 绑定的语法类似于 Property 绑定,但其括号之间不是元素的 Property,而是由前缀 `attr`、点( `.` )和 Attribute 名称组成。然后,你就可以使用能解析为字符串的表达式来设置该 Attribute 的值,或者当表达式解析为 `null` 时删除该 Attribute。
One of the primary use cases for attribute binding
is to set ARIA attributes, as in this example:
attribute 绑定的主要用例之一是设置 ARIA attribute(译注:ARIA 指无障碍功能,用于给残障人士访问互联网提供便利),
就像这个例子中一样:
#### `colspan` and `colSpan`
#### `colspan` 和 `colSpan`
Notice the difference between the `colspan` attribute and the `colSpan` property.
注意 `colspan` Attribute 和 `colSpan` Property 之间的区别。
If you wrote something like this:
如果你这样写:
<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
You'd get this error:
你会收到如下错误:
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
As the message says, the `
` element does not have a `colspan` property. This is true
because `colspan` is an attribute—`colSpan`, with a capital `S`, is the
corresponding property. Interpolation and property binding can set only *properties*, not attributes.
如错误消息所示,`
` 元素没有 `colspan` 这个 Property。这是正确的,因为 `colspan` 是一个 Attribute,而 `colSpan` (`colSpan` 中的 `S` 是大写)则是相应的 Property。插值和 Property 绑定只能设置 *Property*,不能设置 Attribute。
Instead, you'd use property binding and write it like this:
相反,你可以使用 Property 绑定并将其改写为:
### Class binding
### 类绑定
Here's how to set the `class` attribute without a binding in plain HTML:
下面是在普通 HTML 中不用绑定来设置 `class` Attribute 的方法:
```html
Some text
```
You can also add and remove CSS class names from an element's `class` attribute with a **class binding**.
你还可以使用**类绑定**来为一个元素添加和移除 CSS 类。
To create a single class binding, start with the prefix `class` followed by a dot (`.`) and the name of the CSS class (for example, `[class.foo]="hasFoo"`).
Angular adds the class when the bound expression is truthy, and it removes the class when the expression is falsy (with the exception of `undefined`, see [styling delegation](#styling-delegation)).
要创建单个类的绑定,请使用 `class` 前缀,紧跟一个点(`.`),再跟上 CSS 类名,比如 `[class.foo]="hasFoo"`。
当绑定表达式为真值的时候,Angular 就会加上这个类,为假值则会移除,但 `undefined` 是假值中的例外,参见[样式委派](#styling-delegation) 部分。
To create a binding to multiple classes, use a generic `[class]` binding without the dot (for example, `[class]="classExpr"`).
The expression can be a space-delimited string of class names, or you can format it as an object with class names as the keys and truthy/falsy expressions as the values.
With object format, Angular will add a class only if its associated value is truthy.
要想创建多个类的绑定,请使用通用的 `[class]` 形式来绑定类,而不要带点,比如 `[class]="classExpr"`。
该表达式可以是空格分隔的类名字符串,或者用一个以类名为键、真假值表达式为值的对象。
当使用对象格式时,Angular 只会加上那些相关的值为真的类名。
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
一定要注意,在对象型表达式中(如 `object`、`Array`、`Map`、`Set` 等),当这个类列表改变时,对象的引用也必须修改。仅仅修改其属性而不修改对象引用是无法生效的。
If there are multiple bindings to the same class name, conflicts are resolved using [styling precedence](#styling-precedence).
如果有多处绑定到了同一个类名,出现的冲突将根据[样式的优先级规则](#styling-precedence)进行解决。
Binding Type
Syntax
Input Type
Example Input Values
绑定类型
语法
输入类型
输入值范例
Single class binding
[class.foo]="hasFoo"
boolean | undefined | null
true, false
单个类绑定
[class.foo]="hasFoo"
boolean | undefined | null
true, false
Multi-class binding
[class]="classExpr"
string
"my-class-1 my-class-2 my-class-3"
多个类绑定
[class]="classExpr"
string
"my-class-1 my-class-2 my-class-3"
{[key: string]: boolean | undefined | null}
{foo: true, bar: false}
Array<string>
['foo', 'bar']
The [NgClass](#ngclass) directive can be used as an alternative to direct `[class]` bindings.
However, using the above class binding syntax without `NgClass` is preferred because due to improvements in class binding in Angular, `NgClass` no longer provides significant value, and might eventually be removed in the future.
尽管此技术适用于切换单个类名,但在需要同时管理多个类名时请考虑使用 [`NgClass`](guide/template-syntax#ngClass) 指令。
### Style binding
### 样式绑定
Here's how to set the `style` attribute without a binding in plain HTML:
下面演示了如何不通过绑定在普通 HTML 中设置 `style` 属性:
```html
Some text
```
You can also set styles dynamically with a **style binding**.
你还可以通过**样式绑定**来动态设置样式。
To create a single style binding, start with the prefix `style` followed by a dot (`.`) and the name of the CSS style property (for example, `[style.width]="width"`).
The property will be set to the value of the bound expression, which is normally a string.
Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
要想创建单个样式的绑定,请以 `style` 前缀开头,紧跟一个点(`.`),再跟着 CSS 样式的属性名,比如 `[style.width]="width"`。
该属性将会被设置为绑定表达式的值,该值通常为字符串。
不过你还可以添加一个单位表达式,比如 `em` 或 `%`,这时候该值就要是一个 `number` 类型。
Note that a _style property_ name can be written in either
[dash-case](guide/glossary#dash-case), as shown above, or
[camelCase](guide/glossary#camelcase), such as `fontSize`.
注意,*样式属性*命名方法可以用[中线命名法](guide/glossary#dash-case),像上面的一样
也可以用[驼峰式命名法](guide/glossary#camelcase),如 `fontSize`。
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly without the dot (for example, `[style]="styleExpr"`).
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`.
如果要切换多个样式,你可以直接绑定到 `[style]` 属性而不用点(比如,`[style]="styleExpr"`)。赋给 `[style]` 的绑定表达式通常是一系列样式组成的字符串,比如 `"width: 100px; height: 100px;"`。
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
你也可以把该表达式格式化成一个以样式名为键、以样式值为值的对象,比如 `{width: '100px', height: '100px'}`。一定要注意,对于任何对象型的表达式( 如 `object`,`Array`,`Map`,`Set` 等),当这个样式列表改变时,对象的引用也必须修改。仅仅修改其属性而不修改对象引用是无法生效的。。
If there are multiple bindings to the same style property, conflicts are resolved using [styling precedence rules](#styling-precedence).
如果有多处绑定了同一个样式属性,则会使用[样式的优先级规则](#styling-precedence)来解决冲突。
Binding Type
Syntax
Input Type
Example Input Values
绑定类型
语法
输入类型
输入值范例
Single style binding
[style.width]="width"
string | undefined | null
"100px"
单一样式绑定
[style.width]="width"
string | undefined | null
"100px"
Single style binding with units
[style.width.px]="width"
number | undefined | null
100
带单位的单一样式绑定
[style.width.px]="width"
number | undefined | null
100
Multi-style binding
[style]="styleExpr"
string
"width: 100px; height: 100px"
多个样式绑定
[style]="styleExpr"
string
"width: 100px; height: 100px"
{[key: string]: string | undefined | null}
{width: '100px', height: '100px'}
Array<string>
['width', '100px']
The [NgStyle](#ngstyle) directive can be used as an alternative to direct `[style]` bindings.
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
[NgStyle](#ngstyle) 指令可以作为 `[style]` 绑定的替代指令。但是,应该把上面这种 `[style]` 样式绑定语法作为首选,因为随着 Angular 中样式绑定的改进,`NgStyle` 将不再提供重要的价值,并最终在未来的某个版本中删除。
{@a styling-precedence}
### Styling Precedence
### 样式的优先级规则
A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives).
一个 HTML 元素可以把它的 CSS 类列表和样式值绑定到多个来源(例如,来自多个指令的宿主 `host` 绑定)。
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element.
当对同一个类名或样式属性存在多个绑定时,Angular 会使用一组优先级规则来解决冲突,并确定最终哪些类或样式会应用到该元素中。
Styling precedence (highest to lowest)
样式的优先级规则(从高到低)
1. Template bindings
模板绑定
1. Property binding (for example, `
` or `
`)
属性绑定(例如 `
` 或 `
`)
1. Map binding (for example, `
` or `
`)
Map 绑定(例如,`
` 或 `
` )
1. Static value (for example, `
` or `
`)
静态值(例如 `
` 或 `
` )
1. Directive host bindings
指令宿主绑定
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
属性绑定(例如,`host: {'[class.foo]': 'hasFoo'}` 或 `host: {'[style.color]': 'color'}` )
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
Map 绑定(例如,`host: {'[class]': 'classExpr'}` 或者 `host: {'[style]': 'styleExpr'}` )
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
静态值(例如,`host: {'class': 'foo'}` 或 `host: {'style': 'color: blue'}` )
1. Component host bindings
组件宿主绑定
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
属性绑定(例如,`host: {'[class.foo]': 'hasFoo'}` 或 `host: {'[style.color]': 'color'}` )
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
Map 绑定(例如,`host: {'[class]': 'classExpr'}` 或者 `host: {'[style]': 'styleExpr'}` )
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
静态值(例如,`host: {'class': 'foo'}` 或 `host: {'style': 'color: blue'}` )
The more specific a class or style binding is, the higher its precedence.
某个类或样式绑定越具体,它的优先级就越高。
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding.
对具体类(例如 `[class.foo]` )的绑定优先于一般化的 `[class]` 绑定,对具体样式(例如 `[style.bar]` )的绑定优先于一般化的 `[style]` 绑定。
Specificity rules also apply when it comes to bindings that originate from different sources.
It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components.
当处理不同来源的绑定时,也适用这种基于具体度的规则。
某个元素可能在声明它的模板中有一些绑定、在所匹配的指令中有一些宿主绑定、在所匹配的组件中有一些宿主绑定。
Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
模板中的绑定是最具体的,因为它们直接并且唯一地应用于该元素,所以它们具有最高的优先级。
Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings.
指令的宿主绑定被认为不太具体,因为指令可以在多个位置使用,所以它们的优先级低于模板绑定。
Directives often augment component behavior, so host bindings from components have the lowest precedence.
指令经常会增强组件的行为,所以组件的宿主绑定优先级最低。
In addition, bindings take precedence over static attributes.
另外,绑定总是优先于静态属性。
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic.
在下面的例子中,`class` 和 `[class]` 具有相似的具体度,但 `[class]` 绑定优先,因为它是动态的。
{@a styling-delegation}
### Delegating to styles with lower precedence
### 委托优先级较低的样式
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values.
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style.
更高优先级的样式可以使用 `undefined` 值“委托”给低级的优先级样式。虽然把 style 属性设置为 `null` 可以确保该样式被移除,但把它设置为 `undefined` 会导致 Angular 回退到该样式的次高优先级。
For example, consider the following template:
例如,考虑以下模板:
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding.
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.
想象一下,`dirWithHostBinding` 指令和 `comp-with-host-binding` 组件都有 `[style.width]` 宿主绑定。在这种情况下,如果 `dirWithHostBinding` 把它的绑定设置为 `undefined`,则 `width` 属性将回退到 `comp-with-host-binding` 主机绑定的值。但是,如果 `dirWithHostBinding` 把它的绑定设置为 `null`,那么 `width` 属性就会被完全删除。
{@a event-binding}
## Event binding `(event)`
## 事件绑定 `(event)`
Event binding allows you to listen for certain events such as
keystrokes, mouse movements, clicks, and touches. For an example
demonstrating all of the points in this section, see the event binding example.
事件绑定允许你监听某些事件,比如按键、鼠标移动、点击和触屏。要查看本节中所有要点的演示,请参见事件绑定范例。
Angular event binding syntax consists of a **target event** name
within parentheses on the left of an equal sign, and a quoted
template statement on the right.
The following event binding listens for the button's click events, calling
the component's `onSave()` method whenever a click occurs:
Angular 的事件绑定语法由等号左侧带圆括号的**目标事件**和右侧引号中的[模板语句](guide/template-syntax#template-statements)组成。
下面事件绑定监听按钮的点击事件。每当点击发生时,都会调用组件的 `onSave()` 方法。
### Target event
### 目标事件
As above, the target is the button's click event.
如前所述,其目标就是此按钮的单击事件。
Alternatively, use the `on-` prefix, known as the canonical form:
有些人更喜欢带 `on-` 前缀的备选形式,称之为**规范形式**:
Element events may be the more common targets, but Angular looks first to see if the name matches an event property
of a known directive, as it does in the following example:
元素事件可能是更常见的目标,但 Angular 会先看这个名字是否能匹配上已知指令的事件属性,就像下面这个例子:
If the name fails to match an element event or an output property of a known directive,
Angular reports an “unknown directive” error.
如果这个名字没能匹配到元素事件或已知指令的输出属性,Angular 就会报“未知指令”错误。
### *$event* and event handling statements
### *$event* 和事件处理语句
In an event binding, Angular sets up an event handler for the target event.
在事件绑定中,Angular 会为目标事件设置事件处理器。
When the event is raised, the handler executes the template statement.
The template statement typically involves a receiver, which performs an action
in response to the event, such as storing a value from the HTML control
into a model.
当事件发生时,这个处理器会执行模板语句。
典型的模板语句通常涉及到响应事件执行动作的接收器,例如从 HTML 控件中取得值,并存入模型。
The binding conveys information about the event. This information can include data values such as an event object, string, or number named `$event`.
绑定会通过**名叫 `$event` 的事件对象**传递关于此事件的信息(包括数据值)。
The target event determines the shape of the `$event` object.
If the target event is a native DOM element event, then `$event` is a
[DOM event object](https://developer.mozilla.org/en-US/docs/Web/Events),
with properties such as `target` and `target.value`.
事件对象的形态取决于目标事件。如果目标事件是原生 DOM 元素事件,
`$event` 就是 [DOM 事件对象](https://developer.mozilla.org/en-US/docs/Web/Events),它有像 `target` 和 `target.value` 这样的属性。
Consider this example:
考虑这个范例:
This code sets the `` `value` property by binding to the `name` property.
To listen for changes to the value, the code binds to the `input`
event of the `` element.
When the user makes changes, the `input` event is raised, and the binding executes
the statement within a context that includes the DOM event object, `$event`.
上面的代码在把输入框的 `value` 属性绑定到 `name` 属性。
要监听对值的修改,代码绑定到输入框的 `input` 事件。
当用户造成更改时,`input` 事件被触发,并在包含了 DOM 事件对象 (`$event`) 的上下文中执行这条语句。
To update the `name` property, the changed text is retrieved by following the path `$event.target.value`.
要更新 `name` 属性,就要通过路径 `$event.target.value` 来获取更改后的值。
If the event belongs to a directive—recall that components
are directives—`$event` has whatever shape the directive produces.
如果事件属于指令(回想一下,组件是指令的一种),那么 `$event` 具体是什么由指令决定。
### Custom events with `EventEmitter`
### 使用 `EventEmitter` 实现自定义事件
Directives typically raise custom events with an Angular [EventEmitter](api/core/EventEmitter).
The directive creates an `EventEmitter` and exposes it as a property.
The directive calls `EventEmitter.emit(payload)` to fire an event, passing in a message payload, which can be anything.
Parent directives listen for the event by binding to this property and accessing the payload through the `$event` object.
通常,指令使用 Angular [EventEmitter](api/core/EventEmitter) 来触发自定义事件。
指令创建一个 `EventEmitter` 实例,并且把它作为属性暴露出来。
指令调用 `EventEmitter.emit(payload)` 来触发事件,可以传入任何东西作为消息载荷。
父指令通过绑定到这个属性来监听事件,并通过 `$event` 对象来访问载荷。
Consider an `ItemDetailComponent` that presents item information and responds to user actions.
Although the `ItemDetailComponent` has a delete button, it doesn't know how to delete the hero. It can only raise an event reporting the user's delete request.
假设 `ItemDetailComponent` 用于显示英雄的信息,并响应用户的动作。
虽然 `ItemDetailComponent` 包含删除按钮,但它自己并不知道该如何删除这个英雄。
最好的做法是触发事件来报告“删除用户”的请求。
Here are the pertinent excerpts from that `ItemDetailComponent`:
下面的代码节选自 `ItemDetailComponent`:
The component defines a `deleteRequest` property that returns an `EventEmitter`.
When the user clicks *delete*, the component invokes the `delete()` method,
telling the `EventEmitter` to emit an `Item` object.
组件定义了 `deleteRequest` 属性,它是 `EventEmitter` 实例。
当用户点击*删除*时,组件会调用 `delete()` 方法,让 `EventEmitter` 发出一个 `Item` 对象。
Now imagine a hosting parent component that binds to the `deleteRequest` event
of the `ItemDetailComponent`.
现在,假设有个宿主的父组件,它绑定了 `ItemDetailComponent` 的 `deleteRequest` 事件。
When the `deleteRequest` event fires, Angular calls the parent component's
`deleteItem()` method, passing the *item-to-delete* (emitted by `ItemDetail`)
in the `$event` variable.
当 `deleteRequest` 事件触发时,Angular 调用父组件的 `deleteItem` 方法,
在 `$event` 变量中传入*要删除的英雄*(来自 `ItemDetail`)。
### Template statements have side effects
### 模板语句有副作用
Though [template expressions](guide/template-syntax#template-expressions) shouldn't have [side effects](guide/template-syntax#avoid-side-effects), template
statements usually do. The `deleteItem()` method does have
a side effect: it deletes an item.
虽然[模板表达式](guide/template-syntax#template-expressions)不应该有[副作用](guide/template-syntax#avoid-side-effects),但是模板语句通常会有。这里的 `deleteItem()` 方法就有一个副作用:它删除了一个条目。
Deleting an item updates the model, and depending on your code, triggers
other changes including queries and saving to a remote server.
These changes propagate through the system and ultimately display in this and other views.
删除这个英雄会更新模型,还可能触发其它修改,包括向远端服务器的查询和保存。
这些变更通过系统进行扩散,并最终显示到当前以及其它视图中。
{@a two-way}
## Two-way binding `[(...)]`
## 双向绑定 `[(...)]`
Two-way binding gives your app a way to share data between a component class and
its template.
双向绑定为你的应用程序提供了一种在组件类及其模板之间共享数据的方式。
For a demonstration of the syntax and code snippets in this section, see the two-way binding example.
有关本节中语法和代码段的演示,请参见 双向绑定范例。
### Basics of two-way binding
### 双向绑定的基础知识
Two-way binding does two things:
双向绑定会做两件事:
1. Sets a specific element property.
设置特定的元素属性。
1. Listens for an element change event.
监听元素的变更事件。
Angular offers a special _two-way data binding_ syntax for this purpose, `[()]`.
The `[()]` syntax combines the brackets
of property binding, `[]`, with the parentheses of event binding, `()`.
Angular 为此提供了一种特殊*的双向数据绑定*语法 `[()]`。`[()]` 语法将属性绑定的括号 `[]` 与事件绑定的括号 `()` 组合在一起。
[( )] = banana in a box[( )] = 盒子里的香蕉
Visualize a *banana in a box* to remember that the parentheses go _inside_ the brackets.
想象*盒子里的香蕉*来记住方括号套圆括号。
The `[()]` syntax is easy to demonstrate when the element has a settable
property called `x` and a corresponding event named `xChange`.
Here's a `SizerComponent` that fits this pattern.
It has a `size` value property and a companion `sizeChange` event:
`[()]` 语法很容易想明白:该元素具有名为 `x` 的可设置属性和名为 `xChange` 的相应事件。
`SizerComponent` 就是用的这种模式。它具有一个名为 `size` 的值属性和一个与之相伴的 `sizeChange` 事件:
The initial `size` is an input value from a property binding.
Clicking the buttons increases or decreases the `size`, within
min/max value constraints,
and then raises, or emits, the `sizeChange` event with the adjusted size.
`size` 的初始值来自属性绑定的输入值。单击按钮可在最小值/最大值范围内增大或减小 `size`,然后带上调整后的大小发出 `sizeChange` 事件。
Here's an example in which the `AppComponent.fontSizePx` is two-way bound to the `SizerComponent`:
下面的例子中,`AppComponent.fontSize` 被双向绑定到 `SizerComponent`:
The `AppComponent.fontSizePx` establishes the initial `SizerComponent.size` value.
`AppComponent.fontSizePx` 建立初始 `SizerComponent.size` 值。
Clicking the buttons updates the `AppComponent.fontSizePx` via the two-way binding.
The revised `AppComponent.fontSizePx` value flows through to the _style_ binding,
making the displayed text bigger or smaller.
单击按钮就会通过双向绑定更新 `AppComponent.fontSizePx`。修改后的 `AppComponent.fontSizePx` 值将传递到*样式*绑定,从而使显示的文本更大或更小。
The two-way binding syntax is really just syntactic sugar for a _property_ binding and an _event_ binding.
Angular desugars the `SizerComponent` binding into this:
双向绑定语法实际上是*属性*绑定和*事件绑定*的语法糖。
Angular 将 `SizerComponent` 的绑定分解成这样:
The `$event` variable contains the payload of the `SizerComponent.sizeChange` event.
Angular assigns the `$event` value to the `AppComponent.fontSizePx` when the user clicks the buttons.
`$event` 变量包含了 `SizerComponent.sizeChange` 事件的荷载。
当用户点击按钮时,Angular 将 `$event` 赋值给 `AppComponent.fontSizePx`。
### Two-way binding in forms
### 表单中的双向绑定
The two-way binding syntax is a great convenience compared to
separate property and event bindings. It would be convenient to
use two-way binding with HTML form elements like `` and
`