Angular父元件和子元件通過服務來通訊
阿新 • • 發佈:2018-12-22
我們在Angular中可以通過服務來實現子元件和父元件資料的雙向流動。
這張圖揭示了子元件和父元件通過服務來通訊的原理。
我們先用ng new parent-child
來建立一個工程。接下來我們用以下命令生成相應的元件和服務。
生成父元件:
生成子元件:
生成服務:
整個工程的目錄結構如下:
如果要讓資料在多個元件中流動的話,我們就會想到多播,然後我們自然就會想到RxJS中的Subject物件。
共享服務parent.service.ts檔案的程式碼如下:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class ParentService {
// 資料來源 next(發射資料)
private parentToChildSource = new Subject<string>();
private childToParentSource = new Subject<string>();
// 資料流 subscribe(取得資料),在元件中需要訂閱
public parentToChild$ = this.parentToChildSource.asObservable();
public childToParent$ = this.childToParentSource.asObservable();
constructor() { }
public parentToChild(parentDataItem: string) {
this.parentToChildSource.next(parentDataItem);
}
public childToParent(childDataItem: string) {
this.childToParentSource.next(childDataItem);
}
}
父元件具體的程式碼如下:
import { Component, OnInit } from '@angular/core';
import { ParentService } from './parent.service';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css'],
providers: [ParentService]
})
export class ParentComponent implements OnInit {
/**
* 父元件資料
* @type {[string , string , string]}
*/
public parentData = ['來自父元件資料a', '來自父元件資料b', '來自父元件資料c'];
/**
* 儲存來自子元件資料
* @type {Array}
*/
public dataFromChild = [];
public nextData = 0;
constructor(private parentService: ParentService) {
parentService.childToParent$.subscribe(data => {
this.dataFromChild.push(`${data}`);
});
}
ngOnInit() {
}
/**
* 發射資料到子元件
*/
public emissionDataToChild() {
const toChildData = this.parentData[this.nextData++];
this.parentService.parentToChild(toChildData);
if (this.nextData >= this.parentData.length) { this.nextData = 0; }
}
}
父元件模板的程式碼如下:
<p>
<button (click)="emissionDataToChild()">發射資料給子元件</button>
</p>
<ul>
<li *ngFor="let data of dataFromChild">{{data}}</li>
</ul>
<fieldset>
<legend>子元件部分:</legend>
<app-child></app-child>
</fieldset>
子元件具體的程式碼如下:
import { Component, OnDestroy } from '@angular/core';
import { ParentService } from '../parent/parent.service';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnDestroy {
/**
* 子元件的資料
* @type {[string , string , string]}
*/
public childData = ['來自子元件資料a', '來自子元件資料b', '來自子元件資料c'];
/**
* 儲存來自父元件資料
* @type {Array}
*/
public dataFromParent = [];
public nextData = 0;
public subscription: Subscription;
constructor(private parentService: ParentService) {
this.subscription = parentService.parentToChild$.subscribe(data => {
this.dataFromParent.push(`${data}`);
});
}
/**
* 發射資料到父元件
*/
public emissionDataToParent() {
const toParentData = this.childData[this.nextData++];
this.parentService.childToParent(toParentData);
if (this.nextData >= this.childData.length) { this.nextData = 0; }
}
public ngOnDestroy() {
this.subscription.unsubscribe();
}
}
子元件模板的程式碼如下:
<p>
<button (click)="emissionDataToParent()">發射資料到父元件</button>
</p>
<ul>
<li *ngFor="let data of dataFromParent">{{data}}</li>
</ul>
因為服務可以很方便的注入到其它的元件當中,又因為Subject物件可以將資料多播(傳遞)給訂閱了這個物件的元件,因此結合Angular中的service和Rxjs中的Subject可以很方便的實現元件間的資料通訊。
最終程式碼大家可以到這裡來下載:
父元件與子元件通過服務來通訊