angular - 组件销毁并重新访问后,订阅在 ngOnInit 函数中运行

标签 angular rxjs observable subscription behaviorsubject

我在使用 Angular Components 和 rxjs 订阅时遇到了一个非常奇怪的情况。
我有以下 ngOnInitngOnDestroy 函数

ngOnInit() {
    zip(this.service.getMessage, this.service.getType)
      .pipe(takeUntil(this.componentDestroyed$))
      .subscribe(data => {
        const notification = new Notification(data[0], data[1]);
        this.notifications.push(notification);
    });
}

ngOnDestroy(): void {
    this.componentDestroyed$.next(true);
    this.componentDestroyed$.complete();
}
在如下所示的服务文件中使用 Source 和 Subject 范例设置值后,订阅处于事件状态:
private messageSource = new BehaviorSubject<string>('');
private message = this.messageSource.asObservable();
private typeSource = new BehaviorSubject<number>(-1);
private type = this.typeSource.asObservable();

...
...

set setMessage(message: string) {
  this.messageSource.next(message);
}

set setType(type: number) {
  this.typeSource.next(type);
}
正如预期的那样,初始订阅工作正常。但是,离开 Component 并导航回同一个 Component 会在 zip 中再次运行 ngOnInit 订阅,即使在导航离开时组件被销毁后也是如此。如何防止这种情况发生?我还尝试定义订阅变量并调用 unsubscribe 。我难住了。

最佳答案

为了扩展我的评论,RxJS BehaviorSubject s 保存推送给它的当前值并在订阅后立即发出它。它还允许您在 getValue() 上使用唯一的 value 函数(或 BehaviorSubject getter),该函数允许您同步检索它持有的当前值。尽管通常不赞成使用这种 getter。
因此,在您的情况下,当您路由回组件时,订阅会发出两个 observable 先前持有的值。相反,您可以使用 RxJS Subject ,它不保存值并且仅在将值推送给它后才发出。

private messageSource = new Subject<string>();
private message = this.messageSource.asObservable();
private typeSource = new Subject<number>();
private type = this.typeSource.asObservable();
...

我还建议您查看 RxJS ReplaySubject 。这是一个更灵活的多播可观察对象。它接收要缓冲的通知数量,并在新订阅时立即发出它们。
因此 ReplaySubject(1)(缓冲区 1)与 BehaviorSubject 类似,只是它不需要默认值。因此,如果您在尚未推送任何内容时订阅它,它将不会发出。
它对您当前的问题没有帮助,但在您希望拥有 BehaviorSubject 的行为但不希望处理不必要的默认值的情况下可能会有所帮助。

关于angular - 组件销毁并重新访问后,订阅在 ngOnInit 函数中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63091731/

相关文章:

javascript - 使用 switchmap 和 forkjoin 链接 observables 不能按预期工作 angular typescript rxjs

javascript - 包装回调 API 并监听错误?

TypeScript - 等待 observable/promise 完成,然后返回 observable

angular 2 如何对列 ngFor 求和

angular - 预检响应中的 Access-Control-Allow-Headers 不允许请求 header 字段 Access-Control-Allow-Methods

http - 如何在 Angular2 中检查用户是否有互联网连接?

angular - 动态更改 angular2-query-builder 中的配置

rxjs - 可观察的 : Complete vs finally vs done

javascript - 从具有 Angular 2 http 调用的函数返回 Promise,该调用返回 Observable

angular - 对 Observable 的订阅永远不会触发