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

範本變數

Template variables

範本變數可以幫助你在範本的另一部分使用這個部分的資料。使用範本變數,你可以執行某些任務,比如響應使用者輸入或微調應用的表單。

Template variables help you use data from one part of a template in another part of the template. With template variables, you can perform tasks such as respond to user input or finely tune your application's forms.

範本變數可以參考這些東西:

A template variable can refer to the following:

本章包含程式碼片段的工作實例參閱現場演練 / 下載範例

See the現場演練 / 下載範例for a working example containing the code snippets in this guide.

語法

Syntax

在範本中,要使用井號 # 來宣告一個範本變數。下列範本變數 #phone 語法在 <input> 元素上聲明瞭一個名為 phone 的變數

In the template, you use the hash symbol, #, to declare a template variable. The following template variable, #phone, declares a phone variable on an <input> element.

src/app/app.component.html
      
      <input #phone placeholder="phone number" />
    

你可以在元件範本中的任何地方參考某個範本變數。這裡的 <button> 就參考了 phone 變數。

You can refer to a template variable anywhere in the component's template. Here, a <button> further down the template refers to the phone variable.

src/app/app.component.html
      
      <input #phone placeholder="phone number" />

<!-- lots of other elements -->

<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>
    

Angular 是如何為範本變數賦值的

How Angular assigns values to template variables

Angular 根據你所宣告的變數的位置給範本變數賦值:

Angular assigns a template variable a value based on where you declare the variable:

  • 如果在元件上宣告變數,該變數就會參考該元件實例。

    If you declare the variable on a component, the variable refers to the component instance.

  • 如果在標準的 HTML 標記上宣告變數,該變數就會參考該元素。

    If you declare the variable on a standard HTML tag, the variable refers to the element.

  • 如果你在 <ng-template> 元素上宣告變數,該變數就會參考一個 TemplateRef 實例來代表此範本。關於 <ng-template> 的更多資訊,請參閱結構型指令 中的 Angular 如何使用 * 語法部分。

    If you declare the variable on an <ng-template> element, the variable refers to a TemplateRef instance, which represents the template. For more information on <ng-template>, see How Angular uses the asterisk, *, syntax in Structural directives.

  • 如果該變數在右側指定了一個名字,比如 #var="ngModel" ,那麼該變數就會參考所在元素上具有這個 exportAs 名字的指令或元件。

    If the variable specifies a name on the right-hand side, such as #var="ngModel", the variable refers to the directive or component on the element with a matching exportAs name.

NgForm 與範本變數一起使用

Using NgForm with template variables

在大多數情況下,Angular 會把範本變數的值設定為它所在的元素。在前面的例子中, phone 參考的是電話號碼 <input> 。該按鈕的 click 處理程式會把這個 <input> 的值傳給該元件的 callPhone() 方法。

In most cases, Angular sets the template variable's value to the element on which it occurs. In the previous example, phone refers to the phone number <input>. The button's click handler passes the <input> value to the component's callPhone() method.

這裡的 NgForm 指令示範瞭如何透過參考指令的的 exportAs 名字來參考不同的值。在下面的例子中,範本變數 itemForm 在 HTML 中分別出現了三次。

The NgForm directive demonstrates getting a reference to a different value by reference a directive's exportAs name. In the following example, the template variable, itemForm, appears three times separated by HTML.

src/app/hero-form.component.html
      
      <form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
  <label for="name">Name <input class="form-control" name="name" ngModel required />
  </label>
  <button type="submit">Submit</button>
</form>

<div [hidden]="!itemForm.form.valid">
  <p>{{ submitMessage }}</p>
</div>
    

如果沒有 ngForm 這個屬性值,itemForm 參考的值將是 HTMLFormElement 也就是 <form> 元素。而 ComponentDirective 之間的差異在於 Angular 在沒有指定屬性值的情況下,Angular 會參考 Component,而 Directive 不會改變這種隱式參考(即它的宿主元素)。

Without the ngForm attribute value, the reference value of itemForm would be the HTMLFormElement, <form>. There is, however, a difference between a Component and a Directive in that Angular references a Component without specifying the attribute value, and a Directive does not change the implicit reference, or the element.

而使用了 NgForm 之後,itemForm 就是對 NgForm 指令的參考,可以用它來追蹤表單中每一個控制元件的值和有效性。

With NgForm, itemForm is a reference to the NgForm directive with the ability to track the value and validity of every control in the form.

與原生的 <form> 元素不同, NgForm 指令有一個 form 屬性。如果 itemForm.form.valid 無效,那麼 NgFormform 屬性就會讓你禁用提交按鈕。

Unlike the native <form> element, the NgForm directive has a form property. The NgForm form property allows you to disable the submit button if the itemForm.form.valid is invalid.

範本變數的作用域

Template variable scope

你可以在包含此範本變數的範本中的任何地方參考它。而 結構型指令(如 *ngIf*ngFor<ng-template> 同樣充當了範本的邊界。你不能在這些邊界之外訪問其中的範本變數。

You can refer to a template variable anywhere within its surrounding template. Structural directives, such as *ngIf and *ngFor, or <ng-template> act as a template boundary. You cannot access template variables outside of these boundaries.

同名變數在範本中只能定義一次,這樣執行時它的值就是可預測的。

Define a variable only once in the template so the runtime value remains predictable.

在巢狀範本中訪問

Accessing in a nested template

內部範本可以訪問外範本定義的範本變數。

An inner template can access template variables that the outer template defines.

在下面的例子中,修改 <input> 中的文字值也會改變 <span> 中的值,因為 Angular 會立即透過範本變數 ref1 來更新這種變化。

In the following example, changing the text in the <input> changes the value in the <span> because Angular immediately updates changes through the template variable, ref1.

src/app/app.component.html
      
      <input #ref1 type="text" [(ngModel)]="firstExample" />
<span *ngIf="true">Value: {{ ref1.value }}</span>
    

在這種情況下,有一個包含這個 <span> 的隱式 <ng-template>,而該變數的定義在該隱式範本之外。訪問父範本中的範本變數是可行的,因為子範本會從父範本繼承上下文。

In this case, there is an implied <ng-template> around the <span> and the definition of the variable is outside of it. Accessing a template variable from the parent template works because the child template inherits the context from the parent template.

我們用更囉嗦的形式重寫上述的程式碼,可以明確地顯示出 <ng-template>

Rewriting the above code in a more verbose form explicitly shows the <ng-template>.

      
      <input #ref1 type="text" [(ngModel)]="firstExample" />

<!-- New template -->
<ng-template [ngIf]="true">
  <!-- Since the context is inherited, the value is available to the new template -->
  <span>Value: {{ ref1.value }}</span>
</ng-template>
    

但是,從外部的父範本訪問本範本中的變數是行不通的。

However, accessing a template variable from outside the parent template doesn't work.

      
      <input *ngIf="true" #ref2 type="text" [(ngModel)]="secondExample" />
<span>Value: {{ ref2?.value }}</span> <!-- doesn't work -->
    

這個更囉嗦的形式表明 ref2 位於外部的父範本中。

The verbose form shows that ref2 is outside the parent template.

      
      <ng-template [ngIf]="true">
  <!-- The reference is defined within a template -->
  <input #ref2 type="text" [(ngModel)]="secondExample" />
</ng-template>
<!-- ref2 accessed from outside that template doesn't work -->
<span>Value: {{ ref2?.value }}</span>
    

考慮下面這個帶 *ngFor 的使用範例。

Consider the following example that uses *ngFor.

      
      <ng-container *ngFor="let i of [1,2]">
  <input #ref type="text" [value]="i" />
</ng-container>
{{ ref.value }}
    

這裡,ref.value 不起作用。結構型指令 *ngFor 將範本實例化了兩次,因為 *ngFor 在對陣列中的兩個條目進行迭代。因此不可能定義出 ref.value 指向的是誰。

Here, ref.value doesn't work. The structural directive, *ngFor instantiates the template twice because *ngFor iterates over the two items in the array. It is impossible to define what the ref.value reference signifies.

對於結構型指令,比如 *ngFor*ngIf ,Angular 也無法知道範本是否曾被實例化過。

With structural directives, such as *ngFor or *ngIf, there is no way for Angular to know if a template is ever instantiated.

結果,Angular 無法訪問該值並返回錯誤。

As a result, Angular isn't able to access the value and returns an error.

訪問 <ng-template> 的範本變數

Accessing a template variable within <ng-template>

<ng-template> 上宣告變數時,該變數會參考一個 TemplateRef 實例來表示該範本。

When you declare the variable on an <ng-template>, the variable refers to a TemplateRef instance, which represents the template.

src/app/app.component.html
      
      <ng-template #ref3></ng-template>
<button (click)="log(ref3)">Log type of #ref</button>
    

在這個例子中,單擊該按鈕會呼叫 log() 函式,它把 #ref3 的值輸出到控制檯。因為 #ref 變數在 <ng-template> 上,所以它的值是一個 TemplateRef

In this example, clicking the button calls the log() function, which outputs the value of #ref3 to the console. Because the #ref variable is on an <ng-template>, the value is TemplateRef.

下面是一個名為 TemplateRefTemplateRef() 函式在瀏覽器控制檯中展開時的輸出。

The following is the expanded browser console output of the TemplateRef() function with the name of TemplateRef.

      
       ƒ TemplateRef()
name: "TemplateRef"
__proto__: Function
    

範本輸入變數

Template input variable

範本輸入變數是可以在範本的單個實例中參考的變數。你可以用 let 關鍵字宣告範本輸入變數,比如 let hero

A template input variable is a variable you can reference within a single instance of the template. You declare a template input variable using the let keyword as in let hero.

在這個例子中,有幾個這樣的變數:heroiodd

There are several such variables in this example: hero, i, and odd.

此變數的範圍僅限於可複寫範本中的單個實例。你可以在其他結構型指令的定義中再次使用相同的變數名。

The variable's scope is limited to a single instance of the repeated template. You can use the same variable name again in the definition of other structural directives.

相反,你可以透過在變數名稱前加上 # 來宣告範本變數,如 #var。範本變數參考其附加的元素、元件或指令。

In contrast, you declare a template variable by prefixing the variable name with #, as in #var. A template variable refers to its attached element, component, or directive.

範本輸入變數和範本變數名稱具有各自的名稱空間。let hero 中的範本輸入變數 hero#hero 中的範本變數 hero 是不同的。

Template input variables and template variables names have their own namespaces. The template input variable hero in let hero is distinct from the template variable hero in #hero.