在 Angular 中哪里订阅 observable、构造函数或 ngoninit

use*_*050 16 observable typescript ngoninit angular

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

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;
    }
  });
Run Code Online (Sandbox Code Playgroud)

bry*_*n60 23

  1. ngOnInit使用订阅是一个很好的实践,因为@Input绑定直到这个生命周期钩子才被初始化,所以它们在构造函数中还没有准备好,并且通常可观察量可以依赖于这些值。即使他们不这样做,保持一致并且始终在同一个地方也是一个很好的做法。

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


Owe*_*vin 5

我想说最好使用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()
  }
}

Run Code Online (Sandbox Code Playgroud)

使用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) {
  }
}
Run Code Online (Sandbox Code Playgroud)

代码更短,也更容易测试