子元件與父元件之間的資料共享



Angular 提供了在父元件和子元件之間傳遞資料的方法。Angular 提供了兩個裝飾器,@Input 和 @Output。Input 裝飾器使用子元件屬性將值從父元件傳遞到子元件。Output 裝飾器使用子元件發出的事件將值從子元件傳遞到父元件。父元件必須監聽來自子元件的更改事件,捕獲事件資訊並使用它。

讓我們在本節學習如何使用 Input 和 Output 裝飾器。

@Input

配置 Input 裝飾器非常簡單。只需將 Input 裝飾器附加到子元件中的屬性,然後透過子元件屬性從父元件傳遞資料。

假設我們想將計數器從父元件傳遞到子元件。

步驟1:在子元件中建立一個名為 counter 的屬性,並用 @Input 裝飾它。

@Input() counter: number = 0;

這裡:

  • @Input() 是裝飾器

  • counter 是輸入屬性

  • number 是輸入屬性的資料型別,它是可選的

  • 0 是計數器的初始值。如果沒有提供輸入,將使用此值。

步驟2:在父元件中初始化一個變數,例如 counterValue。

counterValue: number = 10

步驟3:使用子元件屬性 (counter) 從父元件傳遞 counter 輸入。

<app-child-component [counter]="counterValue" />

步驟4:最後,根據需要在子元件模板中使用 counter 值。

counter: {{counter}}

讓我們建立兩個元件,父元件和子元件,然後嘗試將資料從父元件傳遞到子元件並在子元件中渲染它。

步驟1:使用 Angular CLI 建立父元件 InOutSample,如下所示:

$ ng generate component InOutSample
CREATE src/app/in-out-sample/in-out-sample.component.css (0 bytes)
CREATE src/app/in-out-sample/in-out-sample.component.html (28 bytes)
CREATE src/app/in-out-sample/in-out-sample.component.spec.ts (596 bytes)
CREATE src/app/in-out-sample/in-out-sample.component.ts (228 bytes)
UPDATE src/app/app.module.ts (1289 bytes)

步驟2:在元件中新增一個 counter 變數,如下所示:

import { Component } from '@angular/core';

@Component({
   selector: 'app-in-out-sample',
   templateUrl: './in-out-sample.component.html',
   styleUrls: ['./in-out-sample.component.css']
})
export class InOutSampleComponent {
   counter: number = 10;
}

步驟3:使用 Angular CLI 建立一個新的子元件 InOutChildSample,如下所示:

$ ng generate component InOutChildSample
CREATE src/app/in-out-child-sample/in-out-child-sample.component.css (0 bytes)
CREATE src/app/in-out-child-sample/in-out-child-sample.component.html (34 bytes)
CREATE src/app/in-out-child-sample/in-out-child-sample.component.spec.ts (632 bytes)
CREATE src/app/in-out-child-sample/in-out-child-sample.component.ts (251 bytes)
UPDATE src/app/app.module.ts (1417 bytes)

步驟4:在子元件中新增一個 counter 屬性,並用 @Input() 裝飾器裝飾它,如下所示:

import { Component, Input } from '@angular/core';

@Component({
   selector: 'app-in-out-child-sample',
   templateUrl: './in-out-child-sample.component.html',
   styleUrls: ['./in-out-child-sample.component.css']
})
export class InOutChildSampleComponent {
   @Input() counter : number = 0;
}

步驟5:開啟子元件模板 in-out-child-sample.component.html 並使用 counter 屬性,如下所示:

<div>
   <p>Counter: {{counter}}</p>
</div>

步驟6:開啟父元件模板 in-out-sample.component.html 並渲染子元件以及 counter 屬性,如下所示:

<app-in-out-child-sample [counter]="counter" />

步驟7:開啟 app 元件的模板並渲染父元件,如下所示:

<app-in-out-sample />

<router-outlet></router-outlet>

步驟8:最後,執行應用程式並檢查計數器是否顯示從父元件傳遞的值,如下所示:

Passed Parent Component

讓我們嘗試使用按鈕和點選事件更改父元件中的 counter 變數,然後檢視它是否會影響子元件。

步驟1:在父元件中新增一個函式來遞增 counter 值,如下所示

inc() {
   this.counter++
}

步驟2:在父元件的模板中新增一個按鈕並繫結該函式,如下所示:

<button (click)="inc()">Increment counter</button>

<app-in-out-child-sample [counter]="counter" />

步驟3:最後,執行應用程式並檢查父元件中變數的更改是否反映在子元件中。

Counter Increment

@Output

Output 裝飾器與 Input 裝飾器非常相似,只是輸出實際上是一個事件發射器,它與事件一起傳遞資料(輸出)。父元件可以訂閱子元件中的事件,並在子元件中資料更改時從子元件獲取發射的值。

步驟1:透過使用 Output 裝飾器建立子元件中的事件發射器。

@Output() counterEvent = new EventEmitter<number>();

步驟2:當子元件中的資料發生更改時發出 counter 事件。

this.counterEvent.emit(changedValue)

步驟3:在父元件中捕獲事件並從回撥函式中獲取資料。

<parent-component (counterEvent)="get($event)" />

步驟4:在父元件中對捕獲的值執行任何操作。

讓我們在子元件 InOutChildSample 元件中編寫一個 Output 裝飾器,並嘗試從父元件 InOutSample 元件獲取輸出。

步驟1:在子元件 in-out-child-sample.component.ts 中建立一個輸出事件發射器,如下所示:

@Output() counterEvent = new EventEmitter<number>();

步驟2:建立一個方法,透過在子元件 in-out-child-sample.component.ts 中發射事件以及 counter 資料來傳遞 counter 的值

passCounterToParent() {
   this.counterEvent.emit(this.counter)
}

子元件的完整列表如下:

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
   selector: 'app-in-out-child-sample',
   templateUrl: './in-out-child-sample.component.html',
   styleUrls: ['./in-out-child-sample.component.css']
})
export class InOutChildSampleComponent {
   @Input() counter : number = 0;
   @Output() counterEvent = new EventEmitter<number>();
   
   passCounterToParent() {
      this.counterEvent.emit(this.counter)
   }

}

步驟3:開啟子元件模板 in-out-child-sample.component.html 並新增一個按鈕,以便在使用者單擊按鈕時呼叫 counter 事件

<div>
   <p>Counter: {{counter}}</p>
   
   <button (click)="passCounterToParent()">Pass Counter to Parent</button>
</div>

這裡:

  • click 是按鈕點選事件,它被配置為在點選時執行 passCounterToParent() 函式。

步驟4:在父元件中新增一個變數來儲存透過子元件事件傳遞的輸出資料。

childCounter: number = 0

步驟5:在父元件中新增一個函式來獲取透過子元件事件傳遞的輸出資料。

get(val: number) {
   this.childCounter = val;
}

父元件的完整列表如下:

import { Component } from '@angular/core';
@Component({
   selector: 'app-in-out-sample',
   templateUrl: './in-out-sample.component.html',
   styleUrls: ['./in-out-sample.component.css']
})
export class InOutSampleComponent {
   counter: number = 10;
   childCounter: number = 0;
   
   inc() {
      this.counter++
   }   
   get(val: number) {
      this.childCounter = val;
   }
}

步驟6:開啟父元件模板 in-out-sample.component.html 並訂閱子元件的事件 counterEvent 並將 get 方法設定為回撥函式,如下所示:

<button (click)="inc()">Increment counter</button>
<p>Data from child: {{childCounter}}</p>
<app-in-out-child-sample [counter]="counter" (counterEvent)="get($event)" />

這裡:

  • counterEvent 是來自子元件的事件

  • counterEvent 是回撥函式。$event 將儲存當前的 counter 值。

  • childContent 是來自子元件的資料

步驟7:最後,執行應用程式,您將看到當單擊子元件中的按鈕時,子元件會將更新的 counter 值傳送到父元件。

updated Counter

總結

Input 和 Output 裝飾器簡化了在父元件和子元件之間傳遞資料,並提供了父元件和子元件之間豐富的互動。

廣告