【问题标题】:Angular Subject and SubscriptionAngular 主题和订阅
【发布时间】:2019-12-12 14:11:38
【问题描述】:

我有一个组件,它有一个方法interval(),当一个按钮被点击时。

 interval() {
    this.statusInterval = interval(2000).subscribe(x => {
      this.interval2 = x;
      console.log(this.interval2);
      this.assetItemActionService.sendNumber(x);
    })
  }

在构造函数中,我有这个订阅,它应该更新那个值。

 interval2 = 0;
 percentSubscription= Subscription;
  constructor(private service:Service) {
    console.log('takeee');
    this.percentSubscription = this.service.number$.subscribe(percent => {
      console.log("set number");
      this.interval2 = percent;
    }, error => console.log(error))
  }

最多 2 个代码片段在同一个组件中。

在服务中,我有这个不断更新的主题。

private number: Subject<number> = new Subject();
number$ = this.number.asObservable();

  sendNumber(number) {
    console.log('received');
    this.number.next(number);
  }

问题是当我路由到另一个页面时,UI 没有更新,构造函数的部分不再工作,我无法订阅,但在控制台中,值每次都会更新。所以 UI 没有呈现,并且在我回到组件后我不能再订阅那个主题了。

我该如何解决这个问题?

【问题讨论】:

  • 您能在 stackblitz 上创建一个最小的复制品吗? stackblitz.com/fork/angular
  • 是的,请 5 分钟
  • 看不到,正常吗?

标签: angular rxjs


【解决方案1】:

您应该unsubscribe 组件中的subscription(s)。

离开组件后您仍然能够在控制台上看到日志这一事实清楚地表明您没有订阅中的unsubscribed,这反过来又会导致内存泄漏。

来,试试看:

import { Component, OnInit } from "@angular/core";
import { Subscription, interval } from "rxjs";

import { NumberService } from "../number.service";

@Component({
  selector: "app-some",
  templateUrl: "./some.component.html",
  styleUrls: ["./some.component.css"]
})
export class SomeComponent implements OnInit {
  interval2 = 0;
  percentSubscription = Subscription;
  statusInterval;

  constructor(private assetItemActionService: NumberService) {
    console.log("takeee");
    this.percentSubscription = this.assetItemActionService.number$.subscribe(
      percent => {
        console.log("set number");
        this.interval2 = percent;
      },
      error => console.log(error)
    );
  }

  ngOnInit() {
    this.interval();
  }

  interval() {
    this.statusInterval = interval(2000).subscribe(x => {
      this.interval2 = x;
      console.log(this.interval2);
      this.assetItemActionService.sendNumber(x);
    });
  }

  ngOnDestroy() {
    this.percentSubscription.unsubscribe();
    this.statusInterval.unsubscribe();
  }
}

PS:您没有指定您在模板中使用的内容。所以我刚刚将路由添加到两个组件(somehello)。


这里有一个Working Demo 供您参考。

【讨论】:

  • 嗨,谢谢你的闪电战,但我的问题是,我想让间隔运行,而我在另一个页面上做其他事情,而不是返回带有间隔和'interval2'计数器的页面并显示当前号码。在您的 some.html 中添加此代码以查看计数器:stackblitz.com/edit/…。或者如果有任何其他方法:)
  • 间隔应该在服务中而不是在组件中。如果您通过路由离开组件,它将被破坏。当您回来时,将创建一个新的组件实例,并且它会有一个新的订阅。因此,保持组件中的间隔将重新初始化它,这不是您想要的。保持服务中的间隔将保留其上的当前值,并且不会一次又一次地重新初始化组件。
  • 谢谢!在组件中,我认为我应该做一个吸气剂来从变量或行为主体中检索该值,对吧?
  • 只需将服务主题的间隔分配给组件上的属性。然后通过async 管道在模板中使用它。这样,您不必显式取消订阅,并且仍然可以避免内存泄漏。 ?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 2021-03-02
  • 2023-03-22
  • 1970-01-01
相关资源
最近更新 更多