在Angular中哪里订阅可观察的,构造函数或ngoninit

问题描述

我知道这是在SO和互联网上发布的,但是我读了很多不同的东西,现在我有点困惑了。

2个问题-

  1. 订阅我的组件,constructor()或NgOnInit()的最佳位置是哪里?
  2. 订阅Observable时应该使用管道,以便Angular可以销毁它,或者我不必使用ngondestroy?订阅后为何会有管道有些困惑?

这是我的一项服务的示例,其中在我的导航栏组件中,我订阅了来自服务的窗口大小更改。

在我的构造函数中,我有这个-

this.responsiveService.getMobileStatus()
  .subscribe(mobileStatus => {
    this.isMobile = mobileStatus.status;
    if (mobileStatus.width < 568) {
      this.inputPlaceholder = this.placeholderWithSearch;
    } else {
      this.inputPlaceholder = this.placeholderWithoutSearch;
    }
  });

解决方法

  1. 使用ngOnInit进行订阅是一个好习惯,因为@Input绑定直到此生命周期钩子才被初始化,因此它们尚未在构造函数中准备好,并且通常可观察对象可以依赖于这些绑定价值观。即使他们不同意,保持一致并且始终在同一位置也是一种很好的做法。

  2. 您应尽可能使用async管道来避免手动订阅管理,但这并不总是可行或合理的。

,

我会说最好使用async管道,并让angular处理取消订阅。它产生更干净的代码;

让我们考虑订阅在构造函数中的代码

export class MyClassComponent implements OnInit,OnDestroy {
  sub: any;
  componentName: any;
  constructor(private navbarService: NavbarService) {
  }
  ngOnInit() {
    this.sub = this.navbarService.getComponentNameObv()
    .subscribe(componentName => {
      this.componentName = componentName;
    });
  }
  ngOnDestroy() {
    this.sub.unsubscribe()
  }
}

使用async管道我们可以重构

export class MyClassComponent {
  componentName$ = this.navbarService.getComponentNameObv();
  mobileStatus$ = this.responsiveService.getMobileStatus().pipe(
    tap(mobileStatus => {
      this.isMobile = mobileStatus.status;
      if (mobileStatus.width < 568) {
        this.inputPlaceholder = this.placeholderWithSearch;
      } else {
        this.inputPlaceholder = this.placeholderWithoutSearch;
      }
    })
  )
  constructor(private navbarService: NavbarService) {
  }
}

代码短得多,也更容易测试