angular - 使用服务的角度多个可观察请求
问题描述
演示在我的应用程序中,我使用服务在
import {Injectable} from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { TransferModel } from '../models/transfer';
@Injectable()
export class TransferService{
constructor(){}
private paramSource = new BehaviorSubject(new TransferModel());
getData = this.paramSource.asObservable();
setData(param:TransferModel) { this.paramSource.next(param)}
}
我的问题是,当我使用组件时,它运行良好,但在页面中也会发送其他页面请求。我的意思是例如我在 Courses.component
constructor(private transferService:TransferService,private dataService:DataService,sessionService:SessionService,private router:Router) {
this.transferService.getData.subscribe(x=>{
this.transfer=x; if(!this.transfer.ExamId || this.transfer.ExamId<=0){ this.router.navigateByUrl("/home");return;}
this.dataService.Post(URLS.url.coursePage.getCourses,{Id:this.transfer.ExamId}).subscribe(elem=>{
this.courses=elem;
});
});
}
当我点击一门课程时,上面的代码获取课程列表,下面的函数运行和
goToSubject(id){
this.transfer.CourseId=id;
this.transferService.setData(this.transfer);
this.router.navigateByUrl("/subjects");
}
转到主题组件。在主题组件中,我使用构造函数发送请求。
constructor(private transferService:TransferService,private dataService:DataService,sessionService:SessionService,private router:Router) {
this.transferService.getData.subscribe(x=>{
this.transfer=x; if(!this.transfer.ExamId || this.transfer.ExamId<=0){ this.router.navigateByUrl("/home"); }
this.dataService.Post(URLS.url.subjectPage.getSubjects,{ExamId:this.transfer.ExamId,CourseId:this.transfer.CourseId}).subscribe(elem=>{
this.subjects=elem;
});
});
}
但这里也有另一个页面的请求调用,例如在图像中。我需要每个页面只发送一个请求。
我怎么解决这个问题?
解决方案
我假设由于transferService.getData()
返回 a Subject
,您正在订阅它,并且可能不会在任何地方取消订阅组件,这些订阅仍然有效并被调用。onDestroy
您的goToSubject()
电话this.transferService.setData(this.transfer);
基本上调用了所有订阅。
当你打电话时,你需要等待Subscription
被退回subscribe
unsubscribe()
ngOnDestroy()
subscription: Subscription;
constructor(...){
this.subscription = this.transferService.getData.subscribe(x=>{
...
});
}
ngOnDestroy() {
if(this.subscription) {
this.subscription.unsubscribe();
this.subscription = null;
}
}
如果您subscribe()
的组件上有多个,也许您想利用某种自订阅实现,例如takeUntil
unsubscribe()
注意:Angular HttpClient 订阅默认是自行取消订阅的,所以调用时不需要调用httpClient.get().subscribe()
. 对于其他一切,您需要调用unsubscribe()
.
更新:
查看您提供的 stackblitz 演示后,确认问题出在transferService.getData()
主题上。然而,即使ngOnDestroy()
取消订阅,它仍然在调用,因为你this.transferService.setData(..)
在重定向之前已经调用了transferService.getData().subscribe(...)
.
要在不进行重大重构的情况下解决此问题,您必须将其设为“仅订阅一次”或“调用订阅后立即自动取消订阅”。这让我们回到takeUntil
.
在 course.component 和 subject.component 中
constructor() {
const subj: Subject<boolean> = new Subject<boolean>();
this.transferService.getData
.pipe(takeUntil(subj))
.subscribe((result) => {
subj.next(true);
});
}
更新 2:
推荐阅读
- java - Mockito 调用主类的方法
- python - 如何在python中将数字缩写(1.70 M,1.600 B,2.1M)转换为整数
- javascript - 开关 - 添加或删除图层
- asp.net-core - 无法在 ASP.NET Core Web API 中上传图像文件 - POST 方法
- reactjs - 如何删除产品已被选中
- c# - 我的带有 MySql 后端数据库代码的 C# 在 VS 2019 中运行良好,但编译后,可执行文件将在第一次查询时中断
- c# - 如何在 C# 中解析这个 jsonobject
- selenium - 尝试在詹金斯上运行硒时出现问题
- javascript - 如果 Javascript 中缺少对象键,则跳过未定义错误
- varnish - 无法将 Varnish 放在端口 80