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

Angular 表單簡介

Introduction to forms in Angular

用表單處理使用者輸入是許多常見應用的基礎功能。 應用透過表單來讓使用者登入、修改個人檔案、輸入敏感資訊以及執行各種資料輸入任務。

Handling user input with forms is the cornerstone of many common applications. Applications use forms to enable users to log in, to update a profile, to enter sensitive information, and to perform many other data-entry tasks.

Angular 提供了兩種不同的方法來透過表單處理使用者輸入:響應式表單和範本驅動表單。 兩者都從檢視中捕獲使用者輸入事件、驗證使用者輸入、建立表單模型、修改資料模型,並提供追蹤這些更改的途徑。

Angular provides two different approaches to handling user input through forms: reactive and template-driven. Both capture user input events from the view, validate the user input, create a form model and data model to update, and provide a way to track changes.

本指南提供的資訊可以幫你確定哪種方式最適合你的情況。它介紹了這兩種方法所用的公共構成要素,還總結了兩種方式之間的關鍵區別,並在建立、資料流和測試等不同的情境下展示了這些差異。

This guide provides information to help you decide which type of form works best for your situation. It introduces the common building blocks used by both approaches. It also summarizes the key differences between the two approaches, and demonstrates those differences in the context of setup, data flow, and testing.

先決條件

Prerequisites

本指南假設你對以下內容有基本的瞭解。

This guide assumes that you have a basic understanding of the following.

選擇一種方法

Choosing an approach

響應式表單和範本驅動表單以不同的方式處理和管理表單資料。每種方法都有各自的優點。

Reactive forms and template-driven forms process and manage form data differently. Each approach offers different advantages.

  • 響應式表單提供對底層表單物件模型直接、顯式的訪問。它們與範本驅動表單相比,更加健壯:它們的可擴充套件性、可複用性和可測試性都更高。如果表單是你的應用程式的關鍵部分,或者你已經在使用響應式表單來建構應用,那就使用響應式表單。

    Reactive forms provide direct, explicit access to the underlying forms object model. Compared to template-driven forms, they are more robust: they're more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms.

  • 範本驅動表單依賴範本中的指令來建立和操作底層的物件模型。它們對於嚮應用新增一個簡單的表單非常有用,比如電子郵件列表登錄檔單。它們很容易新增到應用中,但在擴充套件性方面不如響應式表單。如果你有可以只在範本中管理的非常基本的表單需求和邏輯,那麼範本驅動表單就很合適。

    Template-driven forms rely on directives in the template to create and manipulate the underlying object model. They are useful for adding a simple form to an app, such as an email list signup form. They're easy to add to an app, but they don't scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, template-driven forms could be a good fit.

關鍵差異

Key differences

下表總結了響應式表單和範本驅動表單之間的一些關鍵差異。

The table below summarizes the key differences between reactive and template-driven forms.

響應式

Reactive

範本驅動

Template-driven

建立表單模型

Setup of form model

顯式的,在元件類別中建立

Explicit, created in component class

隱式的,由指令建立

Implicit, created by directives

資料模型

Data model

結構化和不可變的

Structured and immutable

非結構化和可變的

Unstructured and mutable

可預測性

Predictability

同步

Synchronous

非同步

Asynchronous

表單驗證

Form validation

函式

Functions

指令

Directives

可延展性

Scalability

如果表單是應用程式的核心部分,那麼可延展性就非常重要。能夠跨元件複用表單模型是至關重要的。

If forms are a central part of your application, scalability is very important. Being able to reuse form models across components is critical.

響應式表單比範本驅動表單更有可延展性。它們提供對底層表單 API 的直接訪問,以及對表單資料模型的同步訪問,從而可以更輕鬆地建立大型表單。響應式表單需要較少的測試設定,測試時不需要深入理解變更檢測,就能正確測試表單更新和驗證。

Reactive forms are more scalable than template-driven forms. They provide direct access to the underlying form API, and synchronous access to the form data model, making creating large-scale forms easier. Reactive forms require less setup for testing, and testing does not require deep understanding of change detection to properly test form updates and validation.

範本驅動表單專注於簡單的場景,可複用性沒那麼高。它們抽象出了底層表單 API,並且只提供對表單資料模型的非同步訪問。對範本驅動表單的這種抽象也會影響測試。測試程式非常依賴於手動觸發變更檢測才能正常執行,並且需要進行更多設定工作。

Template-driven forms focus on simple scenarios and are not as reusable. They abstract away the underlying form API, and provide only asynchronous access to the form data model. The abstraction of template-driven forms also affects testing. Tests are deeply reliant on manual change detection execution to run properly, and require more setup.

建立表單模型

Setting up the form model

響應式表單和範本驅動型表單都會追蹤使用者與之互動的表單輸入元素和元件模型中的表單資料之間的值變更。這兩種方法共享同一套底層建構塊,只在如何建立和管理常用表單控制元件實例方面有所不同。

Both reactive and template-driven forms track value changes between the form input elements that users interact with and the form data in your component model. The two approaches share underlying building blocks, but differ in how you create and manage the common form-control instances.

常用表單基礎類別

Common form foundation classes

響應式表單和範本驅動表單都建立在下列基礎類別之上。

Both reactive and template-driven forms are built on the following base classes.

  • FormControl 實例用於追蹤單個表單控制元件的值和驗證狀態。

    FormControl tracks the value and validation status of an individual form control.

  • FormGroup 用於追蹤一個表單控制元件組的值和狀態。

    FormGroup tracks the same values and status for a collection of form controls.

  • FormArray 用於追蹤表單控制元件陣列的值和狀態。

    FormArray tracks the same values and status for an array of form controls.

  • ControlValueAccessor 用於在 Angular 的 FormControl 實例和原生 DOM 元素之間建立一個橋樑。

    ControlValueAccessor creates a bridge between Angular FormControl instances and native DOM elements.

建立響應式表單

Setup in reactive forms

對於響應式表單,你可以直接在元件類別中定義表單模型。[formControl] 指令會透過內部值訪問器來把顯式建立的 FormControl 實例與檢視中的特定表單元素聯絡起來。

With reactive forms, you define the form model directly in the component class. The [formControl] directive links the explicitly created FormControl instance to a specific form element in the view, using an internal value accessor.

下面的元件使用響應式表單為單個控制元件實現了一個輸入欄位。在這個例子中,表單模型是 FormControl 實例。

The following component implements an input field for a single control, using reactive forms. In this example, the form model is the FormControl instance.

import { Component } from '@angular/core'; import { FormControl } from '@angular/forms'; @Component({ selector: 'app-reactive-favorite-color', template: ` Favorite Color: <input type="text" [formControl]="favoriteColorControl"> ` }) export class FavoriteColorComponent { favoriteColorControl = new FormControl(''); }
      
      import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-reactive-favorite-color',
  template: `
    Favorite Color: <input type="text" [formControl]="favoriteColorControl">
  `
})
export class FavoriteColorComponent {
  favoriteColorControl = new FormControl('');
}
    

圖 1 展示了在響應式表單中,表單模型是如何成為事實之源(source of truth)的。它透過輸入元素上的 [formControl] 指令,在任何給定的時間點提供表單元素的值和狀態。

Figure 1 shows how, in reactive forms, the form model is the source of truth; it provides the value and status of the form element at any given point in time, through the [formControl] directive on the input element.

圖 1. 在響應式表單中直接訪問表單模型

Figure 1. Direct access to forms model in a reactive form.

建立範本驅動表單

Setup in template-driven forms

在範本驅動表單中,表單模型是隱式的,而不是顯式的。指令 NgModel 為指定的表單元素建立並管理一個 FormControl 實例。

In template-driven forms, the form model is implicit, rather than explicit. The directive NgModel creates and manages a FormControl instance for a given form element.

下面的元件使用範本驅動表單為單個控制元件實現了同樣的輸入欄位。

The following component implements the same input field for a single control, using template-driven forms.

import { Component } from '@angular/core'; @Component({ selector: 'app-template-favorite-color', template: ` Favorite Color: <input type="text" [(ngModel)]="favoriteColor"> ` }) export class FavoriteColorComponent { favoriteColor = ''; }
      
      import { Component } from '@angular/core';

@Component({
  selector: 'app-template-favorite-color',
  template: `
    Favorite Color: <input type="text" [(ngModel)]="favoriteColor">
  `
})
export class FavoriteColorComponent {
  favoriteColor = '';
}
    

在範本驅動表單中,其事實之源就是範本。你沒有對 FormControl 實例的直接程式設計訪問,如圖 2 所示。

In a template-driven form the source of truth is the template. You do not have direct programmatic access to the FormControl instance, as shown in Figure 2.

圖 2. 範本驅動表單中對表單模型的間接訪問。

Figure 2. Indirect access to forms model in a template-driven form.

表單中的資料流

Data flow in forms

當應用包含一個表單時,Angular 必須讓該檢視與元件模型保持同步,並讓元件模型與檢視保持同步。當用戶透過檢視更改值並進行選擇時,新值必須反映在資料模型中。同樣,當程式邏輯改變資料模型中的值時,這些值也必須反映到檢視中。

When an application contains a form, Angular must keep the view in sync with the component model and the component model in sync with the view. As users change values and make selections through the view, the new values must be reflected in the data model. Similarly, when the program logic changes values in the data model, those values must be reflected in the view.

響應式表單和範本驅動表單在處理來自使用者或程式化變更時的資料處理方式上有所不同。下面的這些示意圖會以上面定義的 favorite-color 輸入欄位為例,分別說明兩種表單各自的資料流。

Reactive and template-driven forms differ in how they handle data flowing from the user or from programmatic changes. The following diagrams illustrate both kinds of data flow for each type of form, using the favorite-color input field defined above.

響應式表單中的資料流

Data flow in reactive forms

在響應式表單中,檢視中的每個表單元素都直接連結到一個表單模型(FormControl 實例)。 從檢視到模型的修改以及從模型到檢視的修改都是同步的,而且不依賴於 UI 的渲染方式。

In reactive forms each form element in the view is directly linked to the form model (a FormControl instance). Updates from the view to the model and from the model to the view are synchronous and do not depend on how the UI is rendered.

這個檢視到模型的示意圖展示了當輸入欄位的值發生變化時資料是如何從檢視開始,經過下列步驟進行流動的。

The view-to-model diagram shows how data flows when an input field's value is changed from the view through the following steps.

  1. 終端使用者在輸入框元素中鍵入了一個值,這裡是 "Blue"。

    The user types a value into the input element, in this case the favorite color Blue.

  2. 這個輸入框元素會發出一個帶有最新值的 "input" 事件。

    The form input element emits an "input" event with the latest value.

  3. 這個控制元件值訪問器 ControlValueAccessor 會監聽表單輸入框元素上的事件,並立即把新值傳給 FormControl 實例。

    The control value accessor listening for events on the form input element immediately relays the new value to the FormControl instance.

  4. FormControl 實例會透過 valueChanges 這個可觀察物件發出這個新值。

    The FormControl instance emits the new value through the valueChanges observable.

  5. valueChanges 的任何一個訂閱者都會收到這個新值。

    Any subscribers to the valueChanges observable receive the new value.

這個模型到檢視的示意圖體現了程式中對模型的修改是如何透過下列步驟傳播到檢視中的。

The model-to-view diagram shows how a programmatic change to the model is propagated to the view through the following steps.

  1. favoriteColorControl.setValue() 方法被呼叫,它會更新這個 FormControl 的值。

    The user calls the favoriteColorControl.setValue() method, which updates the FormControl value.

  2. FormControl 實例會透過 valueChanges 這個可觀察物件發出新值。

    The FormControl instance emits the new value through the valueChanges observable.

  3. valueChanges 的任何訂閱者都會收到這個新值。

    Any subscribers to the valueChanges observable receive the new value.

  4. 該表單輸入框元素上的控制元件值訪問器會把控制元件更新為這個新值。

    The control value accessor on the form input element updates the element with the new value.

範本驅動表單中的資料流

Data flow in template-driven forms

在範本驅動表單中,每一個表單元素都是和一個負責管理內部表單模型的指令關聯起來的。

In template-driven forms, each form element is linked to a directive that manages the form model internally.

這個檢視到模型的圖表展示了當輸入欄位的值發生變化時,資料流是如何從檢視開始經過下列步驟進行流動的。

The view-to-model diagram shows how data flows when an input field's value is changed from the view through the following steps.

  1. 終端使用者在輸入框元素中敲 "Blue"。

    The user types Blue into the input element.

  2. 該輸入框元素會發出一個 "input" 事件,帶著值 "Blue"。

    The input element emits an "input" event with the value Blue.

  3. 附著在該輸入框上的控制元件值訪問器會觸發 FormControl 實例上的 setValue() 方法。

    The control value accessor attached to the input triggers the setValue() method on the FormControl instance.

  4. FormControl 實例透過 valueChanges 這個可觀察物件發出新值。

    The FormControl instance emits the new value through the valueChanges observable.

  5. valueChanges 的任何訂閱者都會收到新值。

    Any subscribers to the valueChanges observable receive the new value.

  6. 控制元件值訪問器 ControlValueAccessory 還會呼叫 NgModel.viewToModelUpdate() 方法,它會發出一個 ngModelChange 事件。

    The control value accessor also calls the NgModel.viewToModelUpdate() method which emits an ngModelChange event.

  7. 由於該元件範本雙向資料繫結到了 favoriteColor,元件中的 favoriteColor 屬性就會修改為 ngModelChange 事件所發出的值("Blue")。

    Because the component template uses two-way data binding for the favoriteColor property, the favoriteColor property in the component is updated to the value emitted by the ngModelChange event (Blue).

這個模型到檢視的示意圖展示了當 favoriteColor變到時,資料是如何經過如下步驟從模型流動到檢視的。

The model-to-view diagram shows how data flows from model to view when the favoriteColor changes from Blue to Red, through the following steps

  1. 元件中修改了 favoriteColor 的值。

    The favoriteColor value is updated in the component.

  2. 變更檢測開始。

    Change detection begins.

  3. 在變更檢測期間,由於這些輸入框之一的值發生了變化,Angular 就會呼叫 NgModel 指令上的 ngOnChanges 生命週期鉤子。

    During change detection, the ngOnChanges lifecycle hook is called on the NgModel directive instance because the value of one of its inputs has changed.

  4. ngOnChanges() 方法會把一個非同步任務排入佇列,以設定內部 FormControl 實例的值。

    The ngOnChanges() method queues an async task to set the value for the internal FormControl instance.

  5. 變更檢測完成。

    Change detection completes.

  6. 在下一個檢測週期,用來為 FormControl 實例賦值的任務就會執行。

    On the next tick, the task to set the FormControl instance value is executed.

  7. FormControl 實例透過可觀察物件 valueChanges 發出最新值。

    The FormControl instance emits the latest value through the valueChanges observable.

  8. valueChanges 的任何訂閱者都會收到這個新值。

    Any subscribers to the valueChanges observable receive the new value.

  9. 控制元件值訪問器 ControlValueAccessor 會使用 favoriteColor 的最新值來修改表單的輸入框元素。

    The control value accessor updates the form input element in the view with the latest favoriteColor value.

資料模型的可變性

Mutability of the data model

變更追蹤的方法對應用的效率有著重要影響。

The change-tracking method plays a role in the efficiency of your application.

  • 響應式表單透過以不可變的資料結構提供資料模型,來保持資料模型的純粹性。每當在資料模型上觸發更改時,FormControl 實例都會返回一個新的資料模型,而不會更新現有的資料模型。這使你能夠透過該控制元件的可觀察物件追蹤對資料模型的唯一更改。這讓變更檢測更有效率,因為它只需在唯一性更改(譯註:也就是物件參考發生變化)時進行更新。由於資料更新遵循響應式模式,因此你可以把它和可觀察物件的各種運算子整合起來以轉換資料。

    Reactive forms keep the data model pure by providing it as an immutable data structure. Each time a change is triggered on the data model, the FormControl instance returns a new data model rather than updating the existing data model. This gives you the ability to track unique changes to the data model through the control's observable. Change detection is more efficient because it only needs to update on unique changes. Because data updates follow reactive patterns, you can integrate with observable operators to transform data.

  • 範本驅動的表單依賴於可變性和雙向資料繫結,可以在範本中做出更改時更新元件中的資料模型。由於使用雙向資料繫結時沒有用來對資料模型進行追蹤的唯一性更改,因此變更檢測在需要確定何時更新時效率較低。

    Template-driven forms rely on mutability with two-way data binding to update the data model in the component as changes are made in the template. Because there are no unique changes to track on the data model when using two-way data binding, change detection is less efficient at determining when updates are required.

前面那些使用 favorite-color 輸入元素的例子就示範了這種差異。

The difference is demonstrated in the previous examples that use the favorite-color input element.

  • 對於響應式表單,當控制元件值更新時,FormControl 的實例總會返回一個新值。

    With reactive forms, the FormControl instance always returns a new value when the control's value is updated.

  • 對於範本驅動表單,favorite-color 屬性總會被修改為新值。

    With template-driven forms, the favorite color property is always modified to its new value.

表單驗證

Form validation

驗證是管理任何表單時必備的一部分。無論你是要檢查必填項,還是查詢外部 API 來檢查使用者名稱是否已存在,Angular 都會提供一組內建的驗證器,以及建立自訂驗證器所需的能力。

Validation is an integral part of managing any set of forms. Whether you're checking for required fields or querying an external API for an existing username, Angular provides a set of built-in validators as well as the ability to create custom validators.

  • 響應式表單把自訂驗證器定義成函式,它以要驗證的控制元件作為引數。

    Reactive forms define custom validators as functions that receive a control to validate.

  • 範本驅動表單和範本指令緊密相關,並且必須提供包裝了驗證函式的自訂驗證器指令。

    Template-driven forms are tied to template directives, and must provide custom validator directives that wrap validation functions.

要了解驗證器的更多知識,參閱表單驗證

For more information, see Form Validation.

測試

Testing

測試在複雜的應用程式中也起著重要的作用。當驗證你的表單功能是否正確時,更簡單的測試策略往往也更有用。測試響應式表單和範本驅動表單的差別之一在於它們是否需要渲染 UI 才能基於表單控制元件和表單欄位變化來執行斷言。下面的例子示範了使用響應式表單和範本驅動表單時表單的測試過程。

Testing plays a large part in complex applications. A simpler testing strategy is useful when validating that your forms function correctly. Reactive forms and template-driven forms have different levels of reliance on rendering the UI to perform assertions based on form control and form field changes. The following examples demonstrate the process of testing forms with reactive and template-driven forms.

測試響應式表單

Testing reactive forms

響應式表單提供了相對簡單的測試策略,因為它們能提供對表單和資料模型的同步訪問,而且不必渲染 UI 就能測試它們。在這些測試中,控制元件和資料是透過控制元件進行查詢和操縱的,不需要和變更檢測週期打交道。

Reactive forms provide a relatively easy testing strategy because they provide synchronous access to the form and data models, and they can be tested without rendering the UI. In these tests, status and data are queried and manipulated through the control without interacting with the change detection cycle.

下面的測試利用前面例子中的 "喜歡的顏色" 元件來驗證響應式表單中的 "從檢視到模型" 和 "從模型到檢視" 資料流。

The following tests use the favorite-color components from previous examples to verify the view-to-model and model-to-view data flows for a reactive form.

驗證“從檢視到模型”的資料流

Verifying view-to-model data flow

第一個例子執行了下列步驟來驗證“從檢視到模型”資料流。

The first example performs the following steps to verify the view-to-model data flow.

  1. 查詢表單輸入框元素的檢視,並為測試建立自訂的 "input" 事件

    Query the view for the form input element, and create a custom "input" event for the test.

  2. 把輸入的新值設定為 Red,並在表單輸入元素上排程 "input" 事件。

    Set the new value for the input to Red, and dispatch the "input" event on the form input element.

  3. 斷言該元件的 favoriteColorControl 的值與來自輸入框的值是匹配的。

    Assert that the component's favoriteColorControl value matches the value from the input.

it('should update the value of the input field', () => { const input = fixture.nativeElement.querySelector('input'); const event = createNewEvent('input'); input.value = 'Red'; input.dispatchEvent(event); expect(fixture.componentInstance.favoriteColorControl.value).toEqual('Red'); });
Favorite color test - view to model
      
      it('should update the value of the input field', () => {
  const input = fixture.nativeElement.querySelector('input');
  const event = createNewEvent('input');

  input.value = 'Red';
  input.dispatchEvent(event);

  expect(fixture.componentInstance.favoriteColorControl.value).toEqual('Red');
});
    

下一個例子執行了下列步驟來驗證“從模型到檢視”資料流。

The next example performs the following steps to verify the model-to-view data flow.

  1. 使用 favoriteColorControl 這個 FormControl 實例來設定新值。

    Use the favoriteColorControl, a FormControl instance, to set the new value.

  2. 查詢表單中輸入框的檢視。

    Query the view for the form input element.

  3. 斷言控制元件上設定的新值與輸入中的值是匹配的。

    Assert that the new value set on the control matches the value in the input.

it('should update the value in the control', () => { component.favoriteColorControl.setValue('Blue'); const input = fixture.nativeElement.querySelector('input'); expect(input.value).toBe('Blue'); });
Favorite color test - model to view
      
      it('should update the value in the control', () => {
  component.favoriteColorControl.setValue('Blue');

  const input = fixture.nativeElement.querySelector('input');

  expect(input.value).toBe('Blue');
});
    

測試範本驅動表單

Testing template-driven forms

使用範本驅動表單編寫測試就需要詳細瞭解變更檢測過程,以及指令在每個變更檢測週期中如何執行,以確保在正確的時間查詢、測試或更改元素。

Writing tests with template-driven forms requires a detailed knowledge of the change detection process and an understanding of how directives run on each cycle to ensure that elements are queried, tested, or changed at the correct time.

下面的測試使用了以前的 "喜歡的顏色" 元件,來驗證範本驅動表單的 "從檢視到模型" 和 "從模型到檢視" 資料流。

The following tests use the favorite color components mentioned earlier to verify the data flows from view to model and model to view for a template-driven form.

下面的測試驗證了 "從檢視到模型" 資料流:

The following test verifies the data flow from view to model.

it('should update the favorite color in the component', fakeAsync(() => { const input = fixture.nativeElement.querySelector('input'); const event = createNewEvent('input'); input.value = 'Red'; input.dispatchEvent(event); fixture.detectChanges(); expect(component.favoriteColor).toEqual('Red'); }));
Favorite color test - view to model
      
      it('should update the favorite color in the component', fakeAsync(() => {
     const input = fixture.nativeElement.querySelector('input');
     const event = createNewEvent('input');

     input.value = 'Red';
     input.dispatchEvent(event);

     fixture.detectChanges();

     expect(component.favoriteColor).toEqual('Red');
   }));
    

這個 "檢視到模型" 測試的執行步驟如下:

Here are the steps performed in the view to model test.

  1. 查詢表單輸入元素中的檢視,並為測試建立自訂 "input" 事件。

    Query the view for the form input element, and create a custom "input" event for the test.

  2. 把輸入框的新值設定為 Red,並在表單輸入框元素上派發 "input" 事件。

    Set the new value for the input to Red, and dispatch the "input" event on the form input element.

  3. 透過測試夾具(Fixture)來執行變更檢測。

    Run change detection through the test fixture.

  4. 斷言該元件 favoriteColor 屬性的值與來自輸入框的值是匹配的。

    Assert that the component favoriteColor property value matches the value from the input.

下面的測試驗證了 "從模型到檢視" 的資料流:

The following test verifies the data flow from model to view.

it('should update the favorite color on the input field', fakeAsync(() => { component.favoriteColor = 'Blue'; fixture.detectChanges(); tick(); const input = fixture.nativeElement.querySelector('input'); expect(input.value).toBe('Blue'); }));
Favorite color test - model to view
      
      it('should update the favorite color on the input field', fakeAsync(() => {
     component.favoriteColor = 'Blue';

     fixture.detectChanges();

     tick();

     const input = fixture.nativeElement.querySelector('input');

     expect(input.value).toBe('Blue');
   }));
    

這個 "模型到檢視" 測試的執行步驟如下:

Here are the steps performed in the model to view test.

  1. 使用元件實例來設定 favoriteColor 的值。

    Use the component instance to set the value of the favoriteColor property.

  2. 透過測試夾具(Fixture)來執行變更檢測。

    Run change detection through the test fixture.

  3. fakeAsync() 任務中使用 tick() 方法來模擬時間的流逝。

    Use the tick() method to simulate the passage of time within the fakeAsync() task.

  4. 查詢表單輸入框元素的檢視。

    Query the view for the form input element.

  5. 斷言輸入框的值與該元件實例的 favoriteColor 屬性值是匹配的。

    Assert that the input value matches the value of the favoriteColor property in the component instance.

後續步驟

Next steps

要進一步瞭解響應式表單,參閱下列章節:

To learn more about reactive forms, see the following guides:

要進一步瞭解範本驅動表單,參閱下列章節:

To learn more about template-driven forms, see the following guides: