Angular 组件间传值
一、@Input & @Output & EventEmitter
什么是 @Input?什么是 @Output?
-
@Input
是用于定于模块输入是用于父组件给子组件传值的。 -
@Output
是用于子组件给父组件传值的。@Output
将子组件中的属性标记为数据,从子组件传到父组件,并且使用该属性提出事件,从而通知父组件去进行修改,这里就用到了EventEmiiter
-
EventEmiiter
在组件中使用@Output
指令同步或异步发出自定义事件,并通过订阅实例为这些事件注册处理程序。
如何在组件中使用 @Input & @Output 传值
- 想要在子组件中使用 @Input,首先需要在组件中引入,然后在组件中声明变量。
- 因为需要子组件告知父组件,所有也需要同时引入
@Output
和EventE mitter
,并为其初始化。 - 子组件暴露一个
EventEmitter
属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件这个事件的属性,并在事件发生时作出回应
child.component.ts
import { @Input, @Outpt, EventEmitter } from '@angular/core';
export class ChildrenComponent {
@Input() childStatus = ''
@Output() childStatusChange = new EventEmitter<string>()
addItemEvent(value: string) {
this.childStatusChange.emit(value)
}
}
----------------------------
child.component.html
<label>childStatus: {{ childStatus }} </label>
<button (click)="addItemEvent('子传父')">{{ childStatus }}</button>
父组件
parent.component.ts
export class parentComponent {
parentStatus = '父传子'
}
----------------------------
parent.component.html
<child [(childStatus)]="parentStatus" (childStatusChange)="itemChange">
<label>parentStatus: {{ parentStatus }}
实现效果图如下:
二、基于 RxJs Subject 的组件间通信
实现的思路逻辑
日常工作中不仅仅会有父子之间传值,也会存在兄弟之间传值,@Input 和 @Outout
的方法只能用于父子之间传值并不适用,基于 RXJs Subject
进行的组件间通信没有这个限制。
Subject
这里利用 message
注册的 Subject
来进行 first 组件与 second 组件间通信,first 组件与 second 组件是非父子组件,他们之间的关系如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OOHEcCbC-1634543893977)(https://i.loli.net/2021/10/15/XagPZu7C4eyGfn2.png)]
实现通信的流程如下,这里以打印信息为例
(一)、首先需要先新建一个 message.service.ts
,这个文件主要是存放公共使用的一些方法,变量等,代码如下:
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class MessageService {
messages: string[] = [] // 初始化公共变量
// 声明 subject
private subject = new Subject<any>()
/**
* 用于发送信息
* @param message | string 需要传递的信息
*/
sendMessage(message: string) {
this.subject.next({ text: '嘟嘟嘟,信息来哦' + message })
}
/**
* 用于清空信息栏
*/
clearMessage() {
this.subject.next()
}
/**
* 用于获取信息
* @returns Observable<T> 返回 subject 的数值
*/
getMessage(): Observable<any> {
return this.subject.asObservable()
}
}
(二)、这里我采取 first
和 second
两个组件之间的信息传递,需要注意的是subscribe
记得订阅之后要取消订阅。代码如下:
first.component.ts
export class FirstComponent {
constructor(
private messageService: MessageService
) {}
sendMessage(): void{
this.messageService.sendMessage('first 组件去 second 组件')
}
clearMessage(): void{
this.messageService.clearMessage()
}
}
-------------------------------
first.component.html
<p>first:</p>
<button (click)="sendMessage()">发送信息</button>
<button (click)="clearMessage()">删除信息</button>
second.component.html
<p>second:</p>
<div>
<div *ngIf="message">{{ message.text }}</div>
</div>
---------------------------
second.component.ts
export class SecondComponent implements OnDestroy{
message: any
subscription: Subscription
constructor(
private messageService: MessageSerive
) {
this.subscription = this.messageService.getMessage().subscribe(message => this.message = message)
}
ngOnDestroy(): void {
this.subscription.unsubscribe // 取消订阅
}
}
最后在 app.component.html
将 first
和 second
一并展示出来
<app-first></app-first>
<br/>-----------------
<app-second></app-second>
最后的展示效果如下图: