gpt4 book ai didi

javascript - 使用 rxjs ReplaySubject 在两个组件之间共享数据的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-01 01:19:47 28 4
gpt4 key购买 nike

我开发了一个具有两个 View 的组件。组件 A 有一个联系表单,组件 B 是“谢谢”页面。

组件A:您填写表格并提交。一旦响应到达,就会创建一个新的 ReplaySubject 值。用户将被路由到组件B。

组件B:组件已初始化。组件从主题获取值。 View 已呈现并显示感谢消息。

HTTP 调用响应(表单数据发布请求成功后返回):

{
"status": 200,
"body": {
"message": "We have received your request with the card information below and it will take 48h to be processed. Thank you!",
"card": {
"name": "John Doe",
"email": "john.doe@gmail.com",
"accountNumber": "12345-67890"
}
},
"type": "ItemCreated"
}

组件A(表单)代码:

import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { RequestCardWidgetService } from './request-card-widget.service';
import { RouterService } from '@framework/foundation/core';
import { Item } from '@pt/request-card-data'

@Component({
selector: 'pt-request-card-form',
templateUrl: './request-card-form.template.html',
providers: [RouterService]
})
export class RequestCardFormComponent {
constructor(private fb: FormBuilder, private data: RequestCardWidgetService, private router: RouterService){}

item: Item = {
name: '',
email: '',
accountNumber: ''
};

requestCardForm = this.fb.group({
name: ['', Validators.required],
email: ['', Validators.email],
accountNumber: ['', Validators.required]
})

onSubmit() {
this.item = this.requestCardForm.value;
this.data.requestCard(this.item)
.subscribe(data => {
this.data.processResult(data);
this.router.navigate(['/success']);
});
}

}

组件B(感谢页面)代码:

import { Component } from '@angular/core';
import { RequestCardWidgetService } from './request-card-widget.service';

@Component({
selector: 'pt-request-card-success',
templateUrl: './request-card-success.template.html'
})
export class RequestCardSuccessComponent {
messages: any; // TODO: To use the proper type...

constructor( private requestCardService: RequestCardWidgetService) {
this.messages = this.requestCardService.message;
}
}

组件 B 模板(感谢页面):

<div *ngIf='(messages | async) as msg'>
{{ msg.message}}
</div>

组件服务代码:

import { Injectable } from '@angular/core';
import { HttpResponse } from '@angular/common/http';

import { Observable, ReplaySubject } from 'rxjs';
import { map, take } from 'rxjs/operators';

import {
RequestCardDataService,
Item,
ItemCreated
} from '@example/request-card-data';

@Injectable()
export class RequestCardWidgetService {

constructor(private dataService: RequestCardDataService) { }

private readonly results = new ReplaySubject<ItemCreated>();

readonly message: Observable<ItemCreated> = this.results; // Message Line. This is the variable that I'm rendering in the template. Is this the correct way of extracting subject values?

requestCard (card: Item): Observable<ItemCreated> {
return this.dataService.postCardRecord(card).pipe(
take(1),
map((response: HttpResponse<ItemCreated>): ItemCreated | {} => {
return response.body
? response.body
: {};
})
);
}

processResult(data: ItemCreated) {
this.results.next(data);
}

}

回顾:组件A具有形状。提交表单后,结果将作为新值存储在主题中。用户被路由到感谢页面。感谢页面组件呈现元素并从主题获取最新值。然后它呈现内容。

此代码有效,但我确实有一些问题。

问题:这是使用主题的正确方法吗?

这是:

readonly message: Observable<ItemCreated> = this.results;

从主题中提取值的正确方法? (我正在将“消息”传递给 View 。)

是否有更好的方法来达到相同的结果?预先非常感谢。

最佳答案

这是使用主题的正确方法吗?

ReplaySubect unconstrained 将重放之前发送给新订阅者的所有值。这可能会导致用户可以接收先前发出的消息,直到他们最终收到当前消息。因此,要么限制主题,要么考虑使用 BehaviorSubject反而。

从主题中提取值

一个Subject其所有衍生品都是 ObservableObserver s。向消费者提供主题时,您不希望公开 Observer接口(interface),即消费者永远不能调用 next , errorcomplete 。因此,正如评论中所建议的,您应该确保只公开 Observable首先调用 asObservable 与消费者交互方法。

readonly message: Observable<ItemCreated> = this.results.asObservable();

后续步骤

如果您想继续在组件之间使用基于服务的通信,那么我认为您有机会根据问题评论中链接的文档来清理/优化您的代码。

如果您的应用程序的复杂性将会增加,我会引导您采用 Redux 风格的架构并研究 NgRx具体来说,使用效果来管理副作用。

效果可以通过简单、谨慎的可观察构造满足您的所有要求,即处理表单提交、接收响应、甚至导航到成功页面的效果。 More information about effects can be found here .

对于简单的任务来说,redux 架构可能有些过头了,但如果您正在开发一个管理大型状态树的大型应用程序,我更喜欢这种方法,而不是基于服务的集成。

关于javascript - 使用 rxjs ReplaySubject 在两个组件之间共享数据的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54336187/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com