填寫這份《一分鐘調查》,幫我們(開發組)做得更好!去填寫Home

插值與範本表示式

Interpolation and template expressions

插值能讓你把計算後的字串合併到 HTML 元素標籤之間和屬性賦值語句內的文字中。範本表示式則是用來供你求出這些字串的。

Interpolation allows you to incorporate calculated strings into the text between HTML element tags and within attribute assignments. Template expressions are what you use to calculate those strings.

要了解本指南中涉及的語法和程式碼片段,請參閱現場演練 / 下載範例

See the現場演練 / 下載範例for all of the syntax and code snippets in this guide.

插值 {{...}}

Interpolation {{...}}

所謂 "插值" 是指將表示式嵌入到標記文字中。 預設情況下,插值會用雙花括號 {{}} 作為分隔符。

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

在下面的程式碼片段中,{{ currentCustomer }} 就是插值的例子。

In the following snippet, {{ currentCustomer }} is an example of interpolation.

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

花括號之間的文字通常是元件屬性的名字。Angular 會把這個名字替換為響應元件屬性的字串值。

The text between the braces is often the name of a component property. Angular replaces that name with the string value of the corresponding component property.

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

在上面的示例中,Angular 計算 titleitemImageUrl 屬性並填充空白,首先顯示一些標題文字,然後顯示影象。

In the example above, Angular evaluates the title and itemImageUrl properties and fills in the blanks, first displaying some title text and then an image.

一般來說,括號間的素材是一個範本表示式,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:

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

這個表示式可以呼叫宿主元件的方法,就像下面用的 getVal()

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

<!-- "The sum of 1 + 1 is not 4" --> <p>The sum of 1 + 1 is not {{1 + 1 + getVal()}}.</p>
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 對所有雙花括號中的表示式求值,把求值的結果轉換成字串,並把它們跟相鄰的字串字面量連線起來。最後,把這個組合出來的插值結果賦給元素或指令的屬性

Angular evaluates all expressions in double curly braces, converts the expression results to strings, and links them with neighboring literal strings. Finally, it assigns this composite interpolated result to an element or directive property.

你看上去似乎正在將結果插入元素標籤之間,並將其賦值給屬性。 但實際上,插值是一種特殊語法,Angular 會將其轉換為屬性繫結

You appear to be inserting the result between element tags and assigning it to attributes. However, interpolation is a special syntax that Angular converts into a property binding.

如果你想用別的分隔符來代替 {{}},也可以透過 Component 元資料中的 interpolation 選項來配置插值分隔符。

If you'd like to use something other than {{ and }}, you can configure the interpolation delimiter via the interpolation option in the Component metadata.

範本表示式

Template expressions

範本表示式會產生一個值,並出現在雙花括號 {{ }} 中。 Angular 執行這個表示式,並把它賦值給繫結目標的屬性,這個繫結目標可能是 HTML 元素、元件或指令。

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

{{1 + 1}} 中所包含的範本表示式是 1 + 1。 在屬性繫結中會再次看到範本表示式,它出現在 = 右側的引號中,就像這樣:[property]="expression"

The interpolation braces in {{1 + 1}} surround the template expression 1 + 1. In the property binding, a template expression appears in quotes to the right of the = symbol as in [property]="expression".

在語法上,範本表示式與 JavaScript 很像。很多 JavaScript 表示式都是合法的範本表示式,但也有一些例外。

In terms of syntax, template expressions are similar to JavaScript. Many JavaScript expressions are legal template expressions, with a few exceptions.

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

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

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

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

  • newtypeofinstanceof 等運算子。

    Operators such as new, typeof, instanceof, etc.

  • 使用 ;, 串聯起來的表示式

    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

典型的表示式上下文就是這個元件實例,它是各種繫結值的來源。 在下面的程式碼片段中,雙花括號中的 recommended 和引號中的 itemImageUrl2 所參考的都是 AppComponent 中的屬性。

The expression context is typically the component instance. In the following snippets, the recommended within double curly braces and the itemImageUrl2 in quotes refer to properties of the AppComponent.

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

表示式也可以參考範本中的上下文屬性,例如範本輸入變數,

An expression may also refer to properties of the template's context such as a template input variable,

let customer,或範本參考變數 #customerInput

let customer, or a template reference variable, #customerInput.

<ul> <li *ngFor="let customer of customers">{{customer.name}}</li> </ul>
src/app/app.component.html (template input variable)
      
      <ul>
  <li *ngFor="let customer of customers">{{customer.name}}</li>
</ul>
    
<label>Type something: <input #customerInput>{{customerInput.value}} </label>
src/app/app.component.html (template reference variable)
      
      <label>Type something:
  <input #customerInput>{{customerInput.value}}
</label>
    

表示式中的上下文變數是由範本變數、指令的上下文變數(如果有)和元件的成員疊加而成的。 如果你要參考的變數名存在於一個以上的名稱空間中,那麼,範本變數是最優先的,其次是指令的上下文變數,最後是元件的成員。

The context for terms in an expression is a blend 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, the template variable name takes precedence, followed by a name in the directive's context, and, lastly, the component's member names.

上一個例子中就體現了這種命名衝突。元件具有一個名叫 customer 的屬性,而 *ngFor 聲明瞭一個也叫 customer 的範本變數。

The previous example presents such a name collision. The component has a customer property and the *ngFor defines a customer template variable.

{{customer.name}} 表示式中的 customer 實際參考的是範本變數,而不是元件的屬性。

The customer in {{customer.name}} refers to the template input variable, not the component's property.

範本表示式不能參考全域性名稱空間中的任何東西,比如 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.

表示式使用指南

Expression guidelines

當使用範本表示式時,請遵循下列指南:

When using template expressions follow these guidelines:

簡單

Simplicity

雖然也可以寫複雜的範本表示式,不過最好避免那樣做。

Although it's possible to write complex template expressions, it's a better practice to avoid them.

屬性名或方法呼叫應該是常態,但偶然使用邏輯取反 ! 也是可以的。 其它情況下,應該把應用程式和業務邏輯限制在元件中,這樣它才能更容易開發和測試。

A property name or method call should be the norm, but an occasional Boolean negation, !, is OK. Otherwise, confine application and business logic to the component, where it is easier to develop and test.

快速執行

Quick execution

Angular 會在每個變更檢測週期後執行範本表示式。 變更檢測週期會被多種非同步活動觸發,比如 Promise 解析、HTTP 結果、定時器時間、按鍵或滑鼠移動。

Angular executes template expressions after every change detection cycle. Change detection cycles are triggered by many asynchronous activities such as promise resolutions, HTTP results, timer events, key presses and mouse moves.

表示式應該快速結束,否則使用者就會感到拖沓,特別是在較慢的裝置上。 當計算代價較高時,應該考慮快取那些從其它值計算得出的值。

Expressions should finish quickly or the user experience may drag, especially on slower devices. Consider caching values when their computation is expensive.

沒有可見的副作用

No visible side effects

範本表示式除了目標屬性的值以外,不應該改變應用的任何狀態。

A template expression should not change any application state other than the value of the target property.

這條規則是 Angular “單向資料流”策略的基礎。 永遠不用擔心讀取元件值可能改變另外的顯示值。 在一次單獨的渲染過程中,檢視應該總是穩定的。

This rule is essential to Angular's "unidirectional data flow" policy. You should never worry that reading a component value might change some other displayed value. The view should be stable throughout a single rendering pass.

冪等的表示式是最理想的,因為它沒有副作用,並且可以提高 Angular 的變更檢測效能。 用 Angular 術語來說,冪等表示式總會返回完全相同的東西,除非其依賴值之一發生了變化。

An idempotent expression is ideal because it 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 when called twice in a row. If the expression returns an object, including an array, it returns the same object reference when called twice in a row.

對於 *ngFor,這種行為有一個例外。*ngFor 具有 trackBy 功能,在迭代物件時它可以處理物件的相等性。詳情參見 trackBy 的 *ngFor

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