组件通信及两个或者多个组件之间共享信息的方法;
组件之间通信分为以下几种情况:
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')
}
}