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