使用 RxJS Subject 在两个组件之间传递数据
当谈到 Angular 组件通信时,首先想到的是通过 @Input() 装饰器的父子通信和通过 @Output() 装饰器的子父通信。 这不是在组件之间传递数据的唯一技术。 这里我们将使用 RxJS Subject 在两个组件之间传递数据。 我们唯一需要的是共享文件。 (一些服务文件)。
并且这两个组件不一定是父组件和子组件。
让我们看看我们如何做到这一点。
我们有两个组件 component1 和 component2。 我们的目标是将数据从第一个组件传递到第二个组件。
Component1 包含一些编程语言的名称。 单击发送数据按钮后,它应该填充到第二个组件中。
项目结构
在项目中,我们有 component1、component2 和共享服务文件。
Shared-service 是我们定义的文件 “Subject” 以便在两个组件之间传递数据。
让我们进入编码部分。
共享服务文件
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SharedService {
send_data = new Subject<any>();
constructor() { }
}
component1
<div class="container mt-4">
<div class="row mt-4">
<div class="row mt-2">
<h2>Component 1</h2>
</div>
<div class="row mt-2">
<div class="container d-flex h-100">
<div class="row justify-content-center align-self-center mt-4">
<ul *ngFor="let lang of languages">
<li>{{lang}}</li>
</ul>
<button type="button" class="btn btn-success" (click)="sendData()">Send Data</button>
</div>
</div>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import { SharedService } from '../shared.service';
@Component({
selector: 'app-component1',
templateUrl: './component1.component.html',
styleUrls: ['./component1.component.scss']
})
export class Component1Component implements OnInit {
languages = ['Java', 'Python', 'JavaScript', 'Go']
constructor(private sharedService: SharedService) { }
ngOnInit() {
}
sendData() {
this.sharedService.send_data.next(this.languages)
}
}
在这里,我们有一系列编程语言。 单击发送数据按钮后,该数组将通过 Subject 的 next() 方法发出。
component2
<div class="container mt-4">
<div class="row mt-4">
<div class="row mt-2">
<h2>Component 2</h2>
</div>
<div class="row mt-2">
<div class="container d-flex h-100">
<div class="row justify-content-center align-self-center mt-4">
<ul *ngFor="let lang of languages">
<li>{{lang}}</li>
</ul>
</div>
</div>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { SharedService } from '../shared.service';
@Component({
selector: 'app-component2',
templateUrl: './component2.component.html',
styleUrls: ['./component2.component.scss']
})
export class Component2Component implements OnInit {
languages = []
sub: Subscription
constructor(private sharedService: SharedService) { }
ngOnInit() {
}
ngAfterContentInit() {
this.sub = this.sharedService.send_data.subscribe(
data => {
console.log(data)
this.languages = data
}
)
}
ngOnDestroy() {
if (this.sub) {
this.sub.unsubscribe()
}
}
}
在第二个组件中,我们有一个空的语言数组。 我们要做的是用 component1 给出的数据填充这个数组。
所以,我们使用 ngAfterContentInit 生命周期钩子方法来订阅从 component1 传递过来的数据。 您也可以使用 onInit。
在 onDestroy 中取消订阅已订阅的 observable 是一种很好的做法。
就是这样。 请注意,您也可以使用 EventEmitter 代替 RxJS 主题。 但这不是使用 EventEmitter 传递的子到父数据。
然后它应该在共享服务中定义如下。
@Output() send_data = new EventEmitter<any>()
在 component1 中,我们使用 emit() 而不是 next()。
this.sharedService.send_data.emit(this.languages)
component2 没有任何变化。
让我们看看它是如何运作的。
单击发送数据后,数据已填充到 component2. 我们也可以在 Console 中看到数据。
当需要将数据从一个组件传递到另一个组件时,这种共享数据的方式非常有用。 并且好处是我们可以应用这两个组件,并且本质上不需要父子关系。
它不仅可以用于在两个组件之间传递数据,还可以用于在另一个组件中发生操作时需要在一个组件中发生某些事情时。
希望你觉得这很有帮助。
谢谢!