实现组件交互有很多方式,下面列举。
1.父组件向子组件传递数据:(属性绑定)
父组件 [子属性名] = "父属性名"
<child-content [data]="parentData"></child-content>
子组件通过@Input() data 来获取
@Input() data: any // data可根据使用场景自定义
2.子组件向父组件传递数据:(事件绑定)
子组件使用EventEmitter创建自定义事件,并且通过@Output装饰器将它作为属性暴露出来
import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'child-content', template: `<button (click)="childShow()">这是子组件,广播数据给父组件)</button>` }) export class Child1Component { str: string = '这是子组件数据'; @Output() outShow: EventEmitter<any> = new EventEmitter; constructor(){} childShow2(){ this.str = '这是子组件数据'; this.outShow2.emit(this.str); } }
父组件 通过绑定子组件暴露出来的属性来监听事件从而获取子组件数据
import { Component, ViewChild , ElementRef} from '@angular/core'; import { ChildComponent } from '../child/child.component'; @Component({ template: ` <child1-content (outShow)="parentShow($event)"></child1-content> ` }) export class ParentComponent { parentShow(event) { alert('你好,' + event); } }
3.父组件使用子组件方法:(@ViewChild)
父组件调用子组件的方法需要在组件视图渲染后才能正常运行,否则会报错;可以在生命周期函数AfterViewInit中或之后调用
import { Component, ViewChild , ElementRef} from '@angular/core'; import { ChildComponent } from '../child/child.component'; @Component({ template: ` <button (click)="childViewChild.show1('你好,ViewChild')">ViewChild(获取子组件实例)</button> ` }) export class ParentComponent { str: string = ''; @ViewChild(ChildComponent) childViewChild: ChildComponent; }
child.component.ts 子组件代码
import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'child-content', template: `` }) export class ChildComponent { str: string = '这是子组件数据'; constructor(){} show1(event){ alert('父组件传来的值是:'+ event); } }
4.父组件使用子组件属性与事件:(# 局部变量)
parent..component.ts 父组件代码
import { Component, ViewChild , ElementRef} from '@angular/core'; import { ChildComponent } from '../child/child.component'; @Component({ template: ` <button (click)="child.show1('你好,局部变量!')">局部变量(获取子组件实例)</button> <child-content #child></child-content> selector: 'partvar-content' }) export class ParentComponent { }
child.component.ts 子组件代码(同1.的子组件代码)
5.跨组件传递数据
通过服务Service和RXJS的观察者模式Subject进行通信。
message.service.ts 提供发送/接收的对外方法:
import { Injectable } from "@angular/core"; import { ReplaySubject, Observable } from "rxjs"; @Injectable() export class MessageService { // 这里之所以不用Subject,是想让新加入的观察者能接收到之前的一条广播 private valueUpdated: ReplaySubject<any> = new ReplaySubject<any>(1); constructor() { } sendMessage(val:String) { this.valueUpdated.next(val); } clearMessage(){ this.valueUpdated.next(); } getMessage(): Observable<any> { return this.valueUpdated.asObservable(); } }
使用的地方需要注册message服务
constructor(private message: MessageService) { } ngAfterViewInit(): void { this.subscription = this.message.getMessage().subscribe(msg => { // 根据msg,来处理你的业务逻辑。 }) } // 组件生命周期结束的时候,记得注销一下,不然会卡卡卡卡; ngOnDestroy(): void { this.subscription.unsubscribe(); } // 调用该服务的方法,发送信息; send():void { this.message.sendMessage(2); // 发送信息消息 }
总结:这里的MessageService,就相当于使用广播机制,在所有的组件之间传递信息;不管是数字,字符串,还是对象都是可以传递的,而且这里的传播速度也是很快的