问题描述
我们在logincomponent.ts中使用.pipe(takeuntil)。我需要的是,在成功登录并且用户位于登录页面后,它应该会被破坏。但是,即使用户尝试执行其他活动,并且在目标网页上点击“提交”时,也会调用下面的代码段,这会加载不同的页面,但是“提交”按钮的结果将被覆盖并返回到目标网页。
enter code hereforkJoin({
flag: this.auth
.getEnvironmentSettings('featureEnableQubeScan')
.pipe(take(1)),prefs: this.auth.preferences.pipe(take(1)),}).subscribe(
(result: any) => {
this.qubeScanEnabled = result.flag.featureEnableQubeScan;
this.userPrefs = result.prefs;
// check to see if we're authed (but don't keep listening)
this.auth.authed
.pipe(takeuntilComponentDestroyed(this))
.subscribe((payload: IJwtPayload) => {
if (payload) {
this.auth.accountO
.pipe(takeuntilComponentDestroyed(this))
.subscribe((account: IAccount) => {
if (this.returnUrl) {
this.router.navigateByUrl(this.returnUrl);
} else {
this.router.navigate(['dashboard']);
}
}
}
}
}
);
ngOnDestroy() {}
export function takeuntilComponentDestroyed(component: OnDestroy) {
const componentDestroyed = (comp: OnDestroy) => {
const oldNgOnDestroy = comp.ngOnDestroy;
const destroyed$ = new ReplaySubject<void>(1);
comp.ngOnDestroy = () => {
oldNgOnDestroy.apply(comp);
destroyed$.next(undefined);
destroyed$.complete();
};
return destroyed$;
};
return pipe(
takeuntil(componentDestroyed(component))
);
}
请让我知道我在做什么错。 版本: rxjs:6.5.5 角度:10.0.8 谢谢
解决方法
我已经完成了创建不嵌套订阅并继续具有相同语义的流的第一步。主要区别在于,我可以将takeUntilComponentDestroyed
移动到流的末尾,并让取消订阅的筛选器备份该链。 (这样比较干净,您每次都不会两次运行相同的代码)
这是一个品味问题,但是对于许多人来说,扁平化运算符要容易一些。
enter code hereforkJoin({
flag: this.auth
.getEnvironmentSettings('featureEnableQubeScan')
.pipe(take(1)),prefs: this.auth.preferences.pipe(take(1)),}).pipe(
tap((result: any) => {
this.qubeScanEnabled = result.flag.featureEnableQubeScan;
this.userPrefs = result.prefs;
}),mergeMap((result: any) => this.auth.authed),filter((payload: IJwtPayload) => payload != null),mergeMap((payload: IJwtPayload) => this.auth.accountO),takeUntilComponentDestroyed(this)
).subscribe((account: IAccount) => {
if (this.returnUrl) {
this.router.navigateByUrl(this.returnUrl);
} else {
this.router.navigate(['dashboard']);
}
});
此函数不会创建另一个内部流(destroyed$
)。这种方式可以更简单地回到基础知识,因此,如果没有得到想要的结果,应该更容易调试。
export function takeUntilComponentDestroyed<T>(comp: OnDestroy): MonoTypeOperatorFunction<T> {
return input$ => new Observable(observer => {
const sub = input$.subscribe({
next: val => observer.next(val),complete: () => observer.complete(),error: err => observer.error(err)
});
const oldNgOnDestroy = comp.ngOnDestroy;
comp.ngOnDestroy = () => {
oldNgOnDestroy.apply(comp);
sub.unsubscribe();
observer.complete();
};
return { unsubscribe: () => sub.unsubscribe() };
});
}