【问题标题】:Unable to Unsubscribe from the subscription of ReplaySubject无法退订 ReplaySubject 的订阅
【发布时间】:2019-10-26 00:17:34
【问题描述】:

我已订阅 ReplaySubject 并尝试在 ngOnDestroy 方法中取消订阅。当我离开订阅组件并返回到同一个组件而不发出数据时,它再次被订阅。请问我该如何解决这个问题?

Shared.service.ts

import { Injectable } from '@angular/core';
import { TestCase } from './test-case-form/test-case.model';
import { Subject } from 'rxjs/Subject';
import { ReplaySubject } from 'rxjs/ReplaySubject';


@Injectable({
providedIn: 'root'
})
export class SharedService {
testCasesChanged = new Subject<TestCase[]>();
private startedEditing = new ReplaySubject<number>();
public startedEditing$ = this.startedEditing.asObservable();

setData(index) {
console.log("setData called", index);
this.startedEditing.next(index);
}
}

a.component.ts

export class TestFormComponent implements OnInit, OnDestroy {
@ViewChild('f') testForm : NgForm;
subscription: Subscription;
editIndex: number;
editMode = false;
editedTestCase: TestCase;

private testCases: TestCase[]= [];

ngOnInit() {
this.subscription = this.sharedService.startedEditing$
.subscribe((index: number) => {
console.log("Subscribed");
this.editIndex = index;
this.editMode = true;
this.editedTestCase = 
this.sharedService.getTestCase(this.editIndex);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}

【问题讨论】:

  • 你的意思是你第二次没有得到startedEditing的值?
  • 它正在获取旧值?
  • 是的,它的价值已经过时了
  • 我第二次加载组件而不发出值,但它正在被订阅

标签: angular angular6 angular7


【解决方案1】:

您在ngOnDestroy 中的退订有效。

您在组件中获取旧值,因为您使用的是ReplaySubjectReplaySubject 缓存所有随它发出的值。因此,每次您订阅该主题时,您的 subscribe 方法都会针对您通过此 ReplaySubject 发出的每个值调用。

可以通过以下方式更改缓冲区大小:

// Only the last emitted value is cached and emitted to every new subscriptions
private startedEditing = new ReplaySubject<number>(1); 

如果您只想获取最后发出的值,也可以使用BehaviourSubject

但我猜你只是想使用一个简单的Subject

【讨论】:

  • 我尝试了“private startedEditing = new ReplaySubject(1);”,但它再次自动订阅而没有第二次发出。并且使用主题,它不订阅。不知道是什么问题
  • 你的意思是你的订阅方法又被执行了对吧?
  • 是的,这就是我在回答中解释的,因为ReplaySubject
【解决方案2】:
private startedEditing = new ReplaySubject<number>();

public startedEditing$ = this.startedEditing.asObservable(); 
// `startedEditing$` is no longer `startedEditing` they are now two different things

那么你做

this.startedEditing.next(index);

仅更新startedEditing

startedEditing$ 永远不会在您提供的代码中更新。你能简化并只使用一个吗?

【讨论】:

  • 我试过你的方法,但是当我再次导航到这个组件时,它会自动订阅
猜你喜欢
  • 2019-02-08
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
相关资源
最近更新 更多