填写这份《一分钟调查》,帮我们(开发组)做得更好!去填写Home

文本插值

Text interpolation

文本插值允许你将动态字符串值合并到 HTML 模板中。通过插值,你可以动态更改应用视图中显示的内容,例如显示包含用户名的自定义问候语。

Text interpolation allows you to incorporate dynamic string values into your HTML templates. With interpolation, you can dynamically change what appears in an application view, such as displaying a custom greeting that includes the user's name.

要了解本指南中涉及的语法和代码片段,请参阅现场演练 / 下载范例

See the现场演练 / 下载范例for all of the syntax and code snippets in this guide.

使用插值语法显示值

Displaying values with interpolation

插值是指将表达式嵌入到被标记的文本中。默认情况下,插值使用双花括号 {{}} 作为定界符。

Interpolation refers to embedding expressions into marked up text. By default, interpolation uses the double curly braces {{ and }} as delimiters.

为了说明插值的工作原理,请考虑一个包含 currentCustomer 变量的 Angular 组件:

To illustrate how interpolation works, consider an Angular component that contains a currentCustomer variable:

src/app/app.component.ts
      
      currentCustomer = 'Maria';
    

你可以使用插值在相应的组件模板中显示此变量的值:

You can use interpolation to display the value of this variable in the corresponding component template:

src/app/app.component.html
      
      <h3>Current customer: {{ currentCustomer }}</h3>
    

Angular 会用相应组件属性的字符串值替换掉 currentCustomer。在这里,它的值是 Maria

Angular replaces currentCustomer with the string value of the corresponding component property. In this case, the value is Maria.

在以下示例中,Angular 会求出 titleitemImageUrl 属性的值,以显示一些标题文本和图像。

In the following example, Angular evaluates the title and itemImageUrl properties to display some title text and an image.

src/app/app.component.html
      
      <p>{{title}}</p>
<div><img src="{{itemImageUrl}}"></div>
    

模板表达式

Template expressions

模板表达式会产生一个值,它出现在双花括号 {{ }} 中。 Angular 解析该表达式并将其赋值给绑定目标的某个属性。目标可以是 HTML 元素、组件或指令。

A template expression produces a value and appears within double curly braces, {{ }}. Angular resolves the expression and assigns it to a property of a binding target. The target could be an HTML element, a component, or a directive.

用插值解析表达式

Resolving expressions with interpolation

一般来说,括号间的文本是一个模板表达式,Angular 先对它求值,再把它转换成字符串。 下列插值通过把括号中的两个数字相加说明了这一点:

More generally, the text between the braces is a template expression that Angular first evaluates and then converts to a string. The following interpolation illustrates the point by adding two numbers:

src/app/app.component.html
      
      <!-- "The sum of 1 + 1 is 2" -->
<p>The sum of 1 + 1 is {{1 + 1}}.</p>
    

这些表达式也可以调用宿主组件的方法,就像下面用的 getVal()

Expressions can also invoke methods of the host component such as getVal() in the following example:

src/app/app.component.html
      
      <!-- "The sum of 1 + 1 is not 4" -->
<p>The sum of 1 + 1 is not {{1 + 1 + getVal()}}.</p>
    

通过插值,Angular 执行以下任务:

With interpolation, Angular performs the following tasks:

  1. 计算所有位于双花括号中的表达式。

    Evaluates all expressions in double curly braces.

  2. 将这些表达式的结果转换为字符串。

    Converts the expression results to strings.

  3. 将这些结果融入相邻的字符串文本中。

    Links the results to any adjacent literal strings.

  4. 将融合后的结果赋值给元素或指令的属性。

    Assigns the composite to an element or directive property.

如果你想用别的分隔符来代替 {{}},也可以通过 @Component() 元数据中的 interpolation 选项来配置插值分隔符。

You can configure the interpolation delimiter with the interpolation option in the @Component() metadata.

语法

Syntax

模板表达式和 JavaScript 很相似。许多 JavaScript 表达式都是合法的模板表达式,但以下情况除外。

Template expressions are similar to JavaScript. Many JavaScript expressions are legal template expressions, with the following exceptions.

你不能使用那些具有或可能引发副作用的 JavaScript 表达式,包括:

You can't use JavaScript expressions that have or promote side effects, including:

  • 赋值 (=, +=, -=, ...)

    Assignments (=, +=, -=, ...)

  • 运算符,比如 newtypeofinstanceof 等。

    Operators such as new, typeof, or instanceof

  • 使用 ;, 串联起来的表达式

    Chaining expressions with ; or ,

  • 自增和自减运算符:++--

    The increment and decrement operators ++ and --

  • 一些 ES2015+ 版本的运算符

    Some of the ES2015+ operators

和 JavaScript 语法的其它显著差异包括:

Other notable differences from JavaScript syntax include:

表达式上下文

Expression context

插值表达式具有上下文 —— 表达式所属应用中的特定部分。通常,此上下文就是组件实例。

Interpolated expressions have a context—a particular part of the application to which the expression belongs. Typically, this context is the component instance.

在下面的代码片段中,表达式 recommendeditemImageUrl2 表达式所引用的都是 AppComponent 中的属性。

In the following snippet, the expression recommended and the expression itemImageUrl2 refer to properties of the AppComponent.

src/app/app.component.html
      
      <h4>{{recommended}}</h4>
<img [src]="itemImageUrl2">
    

表达式也可以引用模板上下文中的属性,例如模板输入变量模板引用变量

An expression can also refer to properties of the template's context such as a template input variable or a template reference variable.

下面的例子就使用了模板输入变量 customer

The following example uses a template input variable of customer.

src/app/app.component.html (template input variable)
      
      <ul>
  <li *ngFor="let customer of customers">{{customer.name}}</li>
</ul>
    

接下来的例子使用了模板引用变量 #customerInput

This next example features a template reference variable, #customerInput.

src/app/app.component.html (template reference variable)
      
      <label>Type something:
  <input #customerInput>{{customerInput.value}}
</label>
    

模板表达式不能引用全局命名空间中的任何东西,比如 windowdocument。它们也不能调用 console.logMath.max。 它们只能引用表达式上下文中的成员。

Template expressions cannot refer to anything in the global namespace, except undefined. They can't refer to window or document. Additionally, they can't call console.log() or Math.max() and they are restricted to referencing members of the expression context.

防止命名冲突

Preventing name collisions

表达式求值的上下文是模板变量、指令的上下文对象(如果有的话)以及组件成员的并集。如果所引用的名称在多个命名空间都有,则 Angular 将应用以下逻辑来确定上下文:

The context against which an expression evaluates is the union of the template variables, the directive's context object—if it has one—and the component's members. If you reference a name that belongs to more than one of these namespaces, Angular applies the following logic to determine the context:

  1. 模板变量的名称。

    The template variable name.

  2. 指令上下文中的名称。

    A name in the directive's context.

  3. 组件成员的名称。

    The component's member names.

为避免变量遮盖另一个上下文中的变量,请保持变量名称唯一。在以下示例中,AppComponent 模板在问候 customer Padma。

To avoid variables shadowing variables in another context, keep variable names unique. In the following example, the AppComponent template greets the customer, Padma.

然后,一个 ngFor 列出了 customers 数组中的每个 customer

An ngFor then lists each customer in the customers array.

src/app/app.component.ts
      
      @Component({
  template: `
    <div>
      <!-- Hello, Padma -->
      <h1>Hello, {{customer}}</h1>
      <ul>
        <!-- Ebony and Chiho in a list-->
        <li *ngFor="let customer of customers">{{ customer.value }}</li>
      </ul>
    </div>
  `
})
class AppComponent {
  customers = [{value: 'Ebony'}, {value: 'Chiho'}];
  customer = 'Padma';
}
    

ngFor 中的 customer 处于一个 <ng-template> 的上下文中,所以它指向的是 customers 数组中的 customer,在这里是 Ebony 和 Chiho。此列表中不包含 Padma,因为那个 customer 位于 ngFor 以外的另一个上下文中。反之,<h1> 中的 customer 不包括 Ebony 或 Chiho,因为该 customer 的上下文是组件类,而这个类中 customer 的值是 Padma。

The customer within the ngFor is in the context of an <ng-template> and so refers to the customer in the customers array, in this case Ebony and Chiho. This list does not feature Padma because customer outside of the ngFor is in a different context. Conversely, customer in the <h1> doesn't include Ebony or Chiho because the context for this customer is the class and the class value for customer is Padma.

表达式最佳实践

Expression best practices

使用模板表达式时,请遵循以下最佳实践:

When using template expressions, follow these best practices:

  • 使用短表达式

    Use short expressions

    尽可能使用属性名称或方法调用。将应用和业务逻辑保留在易于开发和测试的组件中。

    Use property names or method calls whenever possible. Keep application and business logic in the component, where it is easier to develop and test.

  • 快速执行

    Quick execution

    Angular 会在每个变更检测周期之后执行模板表达式。许多异步活动都会触发变更检测周期,例如解析 Promise、HTTP 结果、计时器事件、按键和鼠标移动。

    Angular executes template expressions after every change detection cycle. Many asynchronous activities trigger change detection cycles, such as promise resolutions, HTTP results, timer events, key presses and mouse moves.

    表达式应尽快完成,以保持用户体验的性能,尤其是在速度较慢的设备上。当计算值需要更多资源时,请考虑缓存值。

    Expressions should finish quickly to keep the user experience as efficient as possible, especially on slower devices. Consider caching values when their computation requires greater resources.

  • 没有可见的副作用

    No visible side effects

    根据 Angular 的单向数据流模型,除了目标属性的值之外,模板表达式不应更改任何应用状态。读取组件值不应更改其他显示值。该视图应在整个渲染过程中保持稳定。

    According to Angular's unidirectional data flow model, a template expression should not change any application state other than the value of the target property. Reading a component value should not change some other displayed value. The view should be stable throughout a single rendering pass.

    幂等表达式能减少副作用
    Idempotent expressions reduce side effects

    幂等的表达式是最理想的,因为它没有副作用,并且可以提高 Angular 的变更检测性能。 用 Angular 术语来说,幂等表达式总会返回完全相同的东西,除非其依赖值之一发生了变化。

    An idempotent expression is free of side effects and improves Angular's change detection performance. In Angular terms, an idempotent expression always returns exactly the same thing until one of its dependent values changes.

在单独的一次事件循环中,被依赖的值不应该改变。 如果幂等的表达式返回一个字符串或数字,如果连续调用它两次,会返回相同的字符串或数字。 如果幂等的表达式返回一个对象(包括 DateArray),如果连续调用它两次,会返回同一个对象的引用

Dependent values should not change during a single turn of the event loop. If an idempotent expression returns a string or a number, it returns the same string or number if you call it twice consecutively. If the expression returns an object, including an array, it returns the same object reference if you call it twice consecutively.

对于 *ngFor,这种行为有一个例外。*ngFor 具有 trackBy 功能,在迭代对象时它可以正确处理对象值的变化。详情参见 trackBy 的 *ngFor

There is one exception to this behavior that applies to *ngFor. *ngFor has trackBy functionality that can deal with changing values in objects when iterating over them. See *ngFor with trackByfor details.