# 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
### 类绑定
Add and remove CSS class names from an element's `class` attribute with
a **class binding**.
使用**类绑定**可以从元素的 `class` 属性中添加和删除 CSS 类名称。
Here's how to set the attribute without binding in plain HTML:
下面是在普通 HTML 中不用绑定来设置 Attribute 的方法:
```html
Item clearance special
```
Class binding syntax resembles property binding, but instead of an element property between brackets, start with the prefix `class`,
optionally followed by a dot (`.`) and the name of a CSS class: `[class.class-name]`.
类绑定语法类似于 Property 绑定,但其括号之间不是元素的 Property,而是由前缀 `class`、点(`.`)和 CSS 类名(点和 CSS 类名可选)组成 `[class.class-name]` : `[class.class-name]` 。
You can replace that with a binding to a string of the desired class names; this is an all-or-nothing, replacement binding.
可以把它改写为绑定到所需 CSS 类名的绑定;这是一个或者全有或者全无的替换型绑定。
(译注:即当 resetClasses 有值时 class 这个 attribute 设置的内容会被完全覆盖)
You can also add a class to an element without overwriting the classes already on the element:
您还可以将一个类添加到元素上,而不会覆盖该元素上已经存在的类:
Finally, you can bind to a specific class name.
Angular adds the class when the template expression evaluates to truthy.
It removes the class when the expression is falsy.
最后,可以绑定到特定的类名。
当模板表达式的求值结果是真值时,Angular 会添加这个类,反之则移除它。
While this technique is suitable for toggling a single class name,
consider the [`NgClass`](guide/template-syntax#ngClass) directive when
managing multiple class names at the same time.
尽管此技术适用于切换单个类名,但在需要同时管理多个类名时请考虑使用 [`NgClass`](guide/template-syntax#ngClass) 指令。
### Style binding
### 样式绑定
You can set inline styles with a **style binding**.
通过**样式绑定**,可以设置内联样式。
Style binding syntax resembles property binding.
Instead of an element property between brackets, start with the prefix `style`,
followed by a dot (`.`) and the name of a CSS style property: `[style.style-property]`.
样式绑定的语法与属性绑定类似。
但方括号中的部分不是元素的属性名,而由**`style`**前缀,一个点 (`.`)和 CSS 样式的属性名组成。
形如:`[style.style-property]`。
Some style binding styles have a unit extension.
The following example conditionally sets the font size in “em” and “%” units.
有些样式绑定中的样式带有单位。在这里,以根据条件用 “em” 和 “%” 来设置字体大小的单位。
This technique is suitable for setting a single style, but consider
the [`NgStyle`](guide/template-syntax#ngStyle) directive when setting several inline styles at the same time.
此技术适用于设置单个样式,当需要同时设置多个内联样式时请考虑使用 [`NgStyle`](guide/template-syntax#ngStyle) 指令。
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`。
{@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.
假设 `HeroDetailComponent` 用于显示英雄的信息,并响应用户的动作。
虽然 `HeroDetailComponent` 包含删除按钮,但它自己并不知道该如何删除这个英雄。
最好的做法是触发事件来报告“删除用户”的请求。
Here are the pertinent excerpts from that `ItemDetailComponent`:
下面的代码节选自 `HeroDetailComponent`:
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` 发出一个 `Hero` 对象。
Now imagine a hosting parent component that binds to the `deleteRequest` event
of the `ItemDetailComponent`.
现在,假设有个宿主的父组件,它绑定了 `HeroDetailComponent` 的 `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 调用父组件的 `deleteHero` 方法,
在 `$event` 变量中传入*要删除的英雄*(来自 `HeroDetail`)。
### 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
`