我在上上篇文章中介紹了父子組件間通過 Input 和 Output 的交流方式。現在我會介紹組件間交流的其他兩種方法,viewChild 和 data service。我將這篇文章分爲兩部分。首先看 viewChild 部分吧。
通過 viewChild 傳遞數據
什麼是 viewChild?
viewChild 就是准許一個組件被注入到別的組件中。並且指明瞭該可用子組件有了通往父組件的通道。簡單說來,就是如果我們想要子組件的特性,我們就可以使用 viewChild 這個神器。爲了講得詳細點,以下面的代碼爲例。先創建兩個組件,一個爲父組件,另一個爲子組件。 下面是 child.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
counter :number = 0;
IncreaseNumber():void{
this.counter++;
}
constructor() { }
ngOnInit() {
}
}
從這個代碼塊中,我們可以知道,該組件有一個 counter 屬性和一個 IncreaseNumber 方法。每次調用 IncreaseNumber 方法,counter的值就會自增一次。現在我們看看父組件。 parent.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import{ChildComponent} from './child.component'
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
@ViewChild(ChildComponent) private childcomponent : ChildComponent;
Increase():void{
this.childcomponent.IncreaseNumber();
}
Dicrease():void{
this.childcomponent.counter--;
}
constructor() { }
ngOnInit() {
}
}
現在一步步分析上面的代碼塊。
- import {ViewChild} from '@angular/core',再 import進子組件。
@ViewChild(ChildComponent) private childcomponent : ChildComponent;
這句代碼非常重要,用於查詢子組件,並在本地創建的子組件對象 childcomponent 中注入相同的屬性。父組件同樣有兩個方法,自增和自減。父組件的模板可以改成這樣子:
<p>
<b>@ViewChild with Components..</b>
<br>
<br>
<input type="button" (click)="Increase()">
<input type="button" (click)="Decrease()">
<app-child></app-child>
</p>
可以看到,我們在父組件模板中實例化了子組件。
通過 data service 傳遞數據
到目前爲止,我們已經知道了如何在相關組件間傳遞數據,那麼如果是不想關的組件呢?我們通常會用 service 來實現數據傳遞。共享數據背後的思想是共享服務,他將所有被組件中用到的數據同步在一起。就像下面這個例子: 首先來個data service:Data.service.ts
import { Injectable } from '@angular/core';
import {BehaviorSubject} from 'rxjs'
@Injectable()
export class DataService {
private messageSource = new BehaviorSubject < string > ("Start");
constructor() {}
changemessage(message: string): void {
this.messageSource.next(message);
}
}
現在我們來分析一下上面這個代碼塊:
- import { Injectable } from '@angular/core' 引進 @Injectable 裝飾器,這可以讓其他組件和模塊使用該服務類的功能。
- import {BehaviorSubject} from 'rxjs' 這可以返回一種Observable類型,從而訂閱不同類型的消息。這個 service 裏面定義了一種changemessage(),它會返回從 Observable 那裏獲取到的數據。爲了讓各組件可以使用到這個服務,我們需要在根模塊中將這個 service 以 provider:[DataService]的形式引入。 引入該服務的組件 service.component.ts
import { Component, OnInit } from '@angular/core';
import{DataService} from '../data.service';
@Component({
selector: 'app-secondcomponent',
templateUrl: './secondcomponent.component.html',
styleUrls: ['./secondcomponent.component.css']
})
export class SecondcomponentComponent implements OnInit {
childmessage: string = "";
counter:number = 0;
constructor(private data: DataService) {}
ngOnInit() {
this.data.currentmessage.subscribe(Message => this.childMessage);
}
newmessage(): void {
this.data.changemessage("changing counter from sibling " + this.counter++);
}
}
總結:
- 通過 @Injectable 裝飾器添加 service;
- 使用 RxJs 中的 BehaviorSubject,返回數據爲 Observable 類型;
- 訂閱一些可變屬性,在組件中給它重新賦值。
參考:https://dzone.com/articles/angular-component-communication-day-2