Angular 8 - 資料繫結



資料繫結處理如何將元件中的資料繫結到 HTML DOM 元素(模板)。我們可以輕鬆地與應用程式互動,而無需擔心如何插入資料。我們可以透過兩種不同的方式建立連線:單向繫結和雙向繫結。

在進入這個主題之前,讓我們在 Angular 8 中建立一個元件。

開啟命令提示符,並使用以下命令建立新的 Angular 應用程式:

cd /go/to/workspace 
ng new databind-app 
cd databind-app

使用 Angular CLI 建立一個 **test** 元件,如下所示:

ng generate component test

以上操作建立了一個新的元件,輸出如下:

CREATE src/app/test/test.component.scss (0 bytes) CREATE src/app/test/test.component.html (19 bytes) CREATE src/app/test/test.component.spec.ts (614 bytes) 
CREATE src/app/test/test.component.ts (262 bytes) UPDATE src/app/app.module.ts (545 bytes)

使用以下命令執行應用程式:

ng serve

單向資料繫結

**單向資料繫結** 是元件與其模板之間的一種單向互動。如果您在元件中進行任何更改,它將反映在 HTML 元素中。它支援以下型別:

字串插值

通常,**字串插值** 是格式化或操作字串的過程。在 Angular 中,**插值** 用於將資料從元件顯示到檢視(DOM)。它由 {{ }} 表示式表示,也稱為八字鬍語法。

讓我們在元件中建立一個簡單的字串屬性,並將資料繫結到檢視。

將以下程式碼新增到 **test.component.ts** 檔案中,如下所示:

export class TestComponent implements OnInit { 
   appName = "My first app in Angular 8"; 
}

轉到 test.component.html 檔案,並新增以下程式碼:

<h1>{{appName}}</h1>

透過替換現有內容,將 test 元件新增到您的 **app.component.html** 檔案中,如下所示:

<app-test></app-test>

最後,使用以下命令啟動您的應用程式(如果尚未啟動):

ng serve

您可以在螢幕上看到以下輸出:

String interpolation

事件繫結

事件是諸如滑鼠點選、雙擊、懸停或任何鍵盤和滑鼠操作之類的操作。如果使用者與應用程式互動並執行某些操作,則會觸發事件。它由括號 **()** 或 **on-** 表示。我們有不同的方法將事件繫結到 DOM 元素。讓我們簡要了解一下。

元件到檢視繫結

讓我們瞭解簡單的按鈕點選事件處理是如何工作的。

在 **test.component.ts** 檔案中新增以下程式碼,如下所示:

export class TestComponent { 
   showData($event: any){ 
      console.log("button is clicked!"); if($event) { 
         console.log($event.target); 
         console.log($event.target.value); 
      } 
   } 
}

$event*:指的是觸發的事件。在這個場景中,*click* 是事件。* $event 包含有關事件和目標元素的所有資訊。這裡,目標是按鈕。$event.target 屬性將包含目標資訊。

我們有兩種方法可以呼叫元件方法到檢視 **(test.component.html)**。第一個定義如下:

<h2>Event Binding</h2> 
<button (click)="showData($event)">Click here</button>

或者,您可以使用 **字首 - on** 使用規範形式,如下所示:

<button on-click = "showData()">Click here</button>

這裡,我們沒有使用 **$event**,因為它可選。

最後,使用以下命令啟動您的應用程式(如果尚未啟動):

ng serve

現在,執行您的應用程式,您將看到以下響應:

canonical

這裡,當用戶點選按鈕時,事件綁定理解按鈕點選操作並呼叫元件 showData() 方法,所以我們可以得出結論,它是一種單向繫結。

屬性繫結

**屬性繫結** 用於將元件屬性中的資料繫結到 DOM 元素。它由 **[]** 表示。

讓我們透過一個簡單的例子來理解。

在 **test.component.ts** 檔案中新增以下程式碼。

export class TestComponent { 
   userName:string = "Peter"; 
}

在檢視 test.component.html 中進行以下更改,

<input type="text" [value]="userName">

這裡,

**userName** 屬性繫結到 DOM 元素 **** 標籤的屬性。

最後,使用以下命令啟動您的應用程式(如果尚未啟動):

ng serve
Property binding

屬性繫結

**屬性繫結** 用於將元件中的資料繫結到 HTML 屬性。語法如下:

<HTMLTag [attr.ATTR]="Component data">

例如,

<td [attr.colspan]="columnSpan"> ... </td>

讓我們透過一個簡單的例子來理解。

在 **test.component.ts** 檔案中新增以下程式碼。

export class TestComponent { 
   userName:string = "Peter"; 
}

在檢視 **test.component.html** 中進行以下更改,

<input type="text" [value]="userName">

這裡,

userName 屬性繫結到 DOM 元素 標籤的屬性。

最後,使用以下命令啟動您的應用程式(如果尚未啟動):

ng serve
Attribute binding

類繫結

**類繫結** 用於將元件中的資料繫結到 HTML class 屬性。語法如下:

<HTMLTag [class]="component variable holding class name">

**類繫結** 提供了額外的功能。如果元件資料是布林值,則只有在為真時才會繫結類。可以透過字串 (“foo bar”) 和字串陣列提供多個類。還有更多其他選項可用。

例如,

<p [class]="myClasses">

讓我們透過一個簡單的例子來理解。

在 test.component.ts 檔案中新增以下程式碼,

export class TestComponent { 
   myCSSClass = "red"; 
   applyCSSClass = false; 
}

在檢視 **test.component.html** 中進行以下更改。

<p [class]="myCSSClass">This paragraph class comes from *myClass* property </p> 
<p [class.blue]="applyCSSClass">This paragraph class does not apply</p>

在 test.component.css 中新增以下內容。

.red { 
   color: red; 
} 
.blue { 
   color: blue; 
}

最後,使用以下命令啟動您的應用程式(如果尚未啟動):

ng serve

最終輸出將如下所示:

Class binding

樣式繫結

**樣式繫結** 用於將元件中的資料繫結到 HTML style 屬性。語法如下:

<HTMLTag [style.STYLE]="component data">

例如,

<p [style.color]="myParaColor"> ... </p>

讓我們透過一個簡單的例子來理解。

在 **test.component.ts** 檔案中新增以下程式碼。

myColor = 'brown';

在檢視 **test.component.html** 中進行以下更改。

<p [style.color]="myColor">Text color is styled using style binding</p>

最後,使用以下命令啟動您的應用程式(如果尚未啟動):

ng serve

最終輸出將如下所示:

Style binding

雙向資料繫結

**雙向資料繫結** 是一種雙向互動,資料雙向流動(從元件到檢視,以及從檢視到元件)。簡單的例子是 **ngModel**。如果您對屬性(或模型)進行任何更改,它就會反映在您的檢視中,反之亦然。它是屬性和事件繫結的組合。

NgModel

**NgModel** 是一個獨立指令。**ngModel** 指令將表單控制元件繫結到屬性,並將屬性繫結到表單控制元件。**ngModel** 的語法如下:

<HTML [(ngModel)]="model.name" />

例如,

<input type="text" [(ngModel)]="model.name" />

讓我們嘗試在我們的測試應用程式中使用 **ngModel**。

在 **AppModule** (src/app/app.module.ts) 中配置 **FormsModule**

import { FormsModule } from '@angular/forms'; @NgModule({ 
   imports: [ 
      BrowserModule, 
      FormsModule
   ] 
}) 
export class AppModule { }

**FormModule** 執行必要的設定以啟用雙向資料繫結。

更新 **TestComponent** 檢視 **(test.component.html)**,如下所示:

<input type="text" [(ngModel)]="userName" />
<p>Two way binding! Hello {{ userName }}!</p>

這裡,

屬性繫結到表單控制元件 **ngModel** 指令,如果您在文字框中輸入任何文字,它將繫結到該屬性。執行應用程式後,您將看到以下更改:

最後,使用以下命令啟動您的應用程式(如果尚未啟動):

ng serve

現在,執行您的應用程式,您將看到以下響應:

Way Data binding

現在,嘗試將輸入值更改為 **Jack**。在您鍵入時,輸入框下方的文字會發生更改,最終輸出將如下所示:

Two Way Data binding

我們將在接下來的章節中學習更多關於表單控制元件的內容。

工作示例

讓我們在我們的 **ExpenseManager** 應用程式中實現本章中學習的所有概念。

開啟命令提示符並轉到專案根資料夾。

cd /go/to/expense-manager

建立 ExpenseEntry 介面 (src/app/expense-entry.ts) 並新增 id、amount、category、Location、spendOn 和 createdOn。

export interface ExpenseEntry { 
   id: number; 
   item: string; 
   amount: number; 
   category: string; 
   location: string; 
   spendOn: Date; 
   createdOn: Date; 
}

將 **ExpenseEntry** 匯入到 **ExpenseEntryComponent** 中。

import { ExpenseEntry } from '../expense-entry';

建立一個 **ExpenseEntry** 物件,**expenseEntry**,如下所示:

export class ExpenseEntryComponent implements OnInit { 
   title: string; 
   expenseEntry: ExpenseEntry; 
   constructor() { } 
   ngOnInit() { 
      this.title = "Expense Entry"; 
      this.expenseEntry = { 
         id: 1, 
         item: "Pizza", 
         amount: 21, 
         category: "Food", 
         location: "Zomato", 
         spendOn: new Date(2020, 6, 1, 10, 10, 10), createdOn: new Date(2020, 6, 1, 10, 10, 10), 
      }; 
   } 
}

使用 **expenseEntry** 物件更新元件模板,**src/app/expense-entry/expense-entry.component.html**,如下所示:

<!-- Page Content --> 
<div class="container">
   <div class="row"> 
      <div class="col-lg-12 text-center" style="padding-top: 20px;"> 
         <div class="container" style="padding-left: 0px; padding-right: 0px;"> 
            <div class="row"> 
               <div class="col-sm" style="text-align: left;"> 
                  {{ title }} 
               </div> 
               <div class="col-sm" style="text-align: right;"> 
                  <button type="button" class="btn btn-primary">Edit</button> 
               </div> 
            </div> 
         </div> 
         <div class="container box" style="margin-top: 10px;"> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;">  
                  <strong><em>Item:</em></strong> 
               </div> 
               <div class="col" style="text-align: left;"> 
                  {{ expenseEntry.item }} 
               </div> 
            </div> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;"> 
                  <strong><em>Amount:</em></strong> 
               </div> 
               <div class="col" style="text-align: left;">
                  {{ expenseEntry.amount }} 
               </div> 
            </div> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;"> 
                  <strong><em>Category:</em></strong> 
               </div> 
               <div class="col" style="text-align: left;"> 
                  {{ expenseEntry.category }} 
               </div> 
            </div> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;"> 
                  <strong><em>Location:</em></strong> 
               </div> 
               <div class="col" style="text-align: left;"> 
                  {{ expenseEntry.location }} 
               </div> 
            </div> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;">
                  <strong><em>Spend On:</em></strong>
               </div> 
               <div class="col" style="text-align: left;"> 
                  {{ expenseEntry.spendOn }} 
               </div> 
            </div> 
         </div> 
      </div> 
   </div> 
</div>
NgModel
廣告