組件通信及兩個或者多個組件之間共享信息的方法;
組件之間通信分爲以下幾種情況:
1、父組件向子組件傳遞數據;
2、 子組件向父組件傳遞數據;
3、非嵌套組件之間的通信;
下面將詳細說明如何實現這幾種通信
父組件向子組件傳遞數據:屬性綁定方式([屬性名])
子組件中通過@Input 裝飾器自定義屬性,父組件綁定這個屬性。
子組件實現:
import { Component, OnInit,Input } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() private data: any;//data名字根據引用場景自定義
constructor() { }
ngOnInit() {
}
}
父組件實現:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parent',
template: `<app-child [data]="dataToChild"></app-child>`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
private dataToChild: string = ' I am parent';
constructor() { }
ngOnInit() {
}
}
子組件向父組件傳遞數據:事件綁定 父組件監聽子組件事件
子組件使用EventEmitter創建自定義事件,並且通過@Output()裝飾器把它作爲屬性暴露出來,父組件通過綁定這個屬性來監聽事件從而獲取子組件數據。
子組件實現:
import { Component, OnInit} from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Output() onCustomEvent: EventEmitter<any> = new EventEmitter();//創建實力
constructor() { }
ngOnInit() {
}
//
private emitEvent(){
this.onCustomEvent.emit('data from child');//通過emit可將需要傳遞的數據發送給父組件
}
}
父組件實現:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parent',
template: `<app-child (onCustomEvent)="onCustom($event)"></app-child>`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
constructor() { }
ngOnInit() {
}
onCustom($event){
console.log($event);//data from child
}
}
非嵌套組件之間通信:通過服務來通信基於RXJS,該方法也可用於嵌套組件之間的通信
父組件和子組件通過共享一個服務,利用該服務實現雙向通信。
服務的定義:
import {Injectable} from "@angular/core";
import {ReplaySubject} from "rxjs/ReplaySubject";
import { Observable } from "rxjs/Observable";
@Injectable()
export class CommunicateService{
private _sendMessage: ReplaySubject<any> = new ReplaySubject<any>(1);
/** * 向其他組件發送信息 * @param message 需要發送的信息 * @returns {Observavle<any>} */
public sendMessage(message: any): Observavle<any>{
this._sendMessage.next(message);
}
/** *訂閱其他組件發送來的消息 * @returns {Observalue<any>} */
public getMessage(): Observable <any>{
return this._sendMessage.asObservable();
}
}
在一個組件中發佈消息,通過服務中定義的sendMessage可廣播一條消息,如果其他組件定於了這條消息,則可接收到
import { Component, OnInit} from '@angular/core';
import {CommunicateService} from "commucate.service"
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor(private communicateService:CommunicateService) { }
ngOnInit() {
this.communicateService.sendMessage('send a message');//發佈一條消息
}
}
在組件中訂閱消息
import { Component, OnInit } from '@angular/core';
import {CommunicateService} from "commucate.service";
@Component({
selector: 'app-parent',
template: `<div>hi</div>`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
constructor(private communicateService:CommunicateService) { }
ngOnInit() {
this.communicateService.getMessage().subscribe((message: any)=>{
console.log(message);//send a message
});
}
}
父組件使用子組件的方法: 使用@ViewChild
父組件調用子組件的方法需要在組件視圖渲染後可能正常運行,否則會報錯;及在生命週期函數AfterViewInit中或者之後調用子組件方法。
子組件實現:在子組件定義公共方法onChildMethod
import { Component, OnInit} from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor() { }
ngOnInit() {
}
public onChildMethod(){
console.log('I am child Method')
}
}
父組件實現:父組件通過@ViewChild裝飾器可調用子組件中的方法
import { Component, OnInit,ViewChild ,AfterViewInit} from '@angular/core';
import {ChildComponent} from "../child/child.component";
@Component({
selector: 'app-parent',
template: `<app-child #child></app-child>`,//定義本地變量child
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit,AfterViewInit {
@ViewChild('child') //child在模版中定義的變量
private myChild: ChildComponent;
//or
// @Viewchild(ChildComponent)
// private myChild: ChildComponent;
constructor() { }
ngOnInit() {
}
ngAfterViewInit(){
this.myChild.onChildMethond()//I am child Method
}
}
子組件調用父組件方法;@Inject注入裝飾器實現
子組件實現方式:
import {Component, Inject, OnInit} from '@angular/core';
import {ParentComponent} from "../parent/parent.component";
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor(@Inject(ParentComponent) private data: any) {
data.sayHello();//調用父組件方法
}
ngOnInit() {
}
}
父組件實現方式:在父組件中定義供子組件使用的方法
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-parent',
template: `<app-child></app-child>`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
constructor() {}
ngOnInit() {}
public sayHello() {
console.log('hello')
}
}