服务中的Angular 4+ ngOnDestroy() - 破坏可观察的

mpe*_*rle 70 observable rxjs angular-services angular

在角度应用程序中,我们有ngOnDestroy()一个组件/指令的生命周期钩子,我们使用这个钩子取消订阅observables.

我想清除/ @injectable()服务中创建的destory observable .我看到一些帖子说ngOnDestroy()可以在服务中使用.

但是,这是一个很好的做法,只有这样才能这样做,什么时候会被召唤?有人请澄清一下.

Est*_*ask 85

提供程序中提供了OnDestroy生命周期钩子.根据文件:

销毁指令,管道或服务时调用的生命周期钩子.

这是一个例子:

@Injectable()
class Service implements OnDestroy {
  ngOnDestroy() {
    console.log('Service destroy')
  }
}

@Component({
  selector: 'foo',
  template: `foo`,
  providers: [Service]
})
export class Foo {
  constructor(service: Service) {}

  ngOnDestroy() {
    console.log('foo destroy')
  }
}

@Component({
  selector: 'my-app',
  template: `<foo *ngIf="isFoo"></foo>`,
})
export class App {
  isFoo = true;

  constructor() {
    setTimeout(() => {
        this.isFoo = false;
    }, 1000)
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的代码中Service是一个属于Foo组件的实例,因此可以在销毁时Foo将其销毁.

对于属于根注入器的提供程序,这将在应用程序销毁时发生,这有助于避免多个引导的内存泄漏,即在测试中.

当父注入器中的提供者在子组件中订阅时,它不会在组件销毁时被销毁,这是组件在组件中取消订阅的责任ngOnDestroy(另一个答案解释).

  • Plunker 不适合我,所以这里是该示例的 StackBlitz 版本:https://stackblitz.com/edit/angular-mggk9b (3认同)

Ara*_*ind 20

在您的服务中创建变量

subscriptions: Subscriptions[]=[];
Run Code Online (Sandbox Code Playgroud)

将每个订阅推送到数组

this.subscriptions.push(...)
Run Code Online (Sandbox Code Playgroud)

写一个dispose()方法

dispose(){
this.subscriptions.forEach(subscription =>subscription.unsubscribe())
Run Code Online (Sandbox Code Playgroud)

在ngOnDestroy期间从组件中调用此方法

ngOnDestroy(){
   this.service.dispose();
 }
Run Code Online (Sandbox Code Playgroud)

  • 生命周期挂钩不适用于`@ injectables` (2认同)

Mat*_*iba 6

我更喜欢takeUntil(onDestroy$)由可点运算符启用的这种模式。我喜欢这种模式更简洁,更简洁,并且清楚地传达了在执行OnDestroy生命周期挂钩时终止订阅的意图。

此模式适用于服务以及订阅已注入可观察对象的组件。下面的框架代码应为您提供足够的详细信息,以将模式集成到您自己的服务中。假设您要导入一个名为InjectedService...

import { InjectedService } from 'where/it/lives';
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class MyService implements OnDestroy {

  private onDestroy$ = new Subject<boolean>();

  constructor(
    private injectedService: InjectedService
  ) {
    // Subscribe to service, and automatically unsubscribe upon `ngOnDestroy`
    this.injectedService.observableThing().pipe(
      takeUntil(this.onDestroy$)
    ).subscribe(latestTask => {
      if (latestTask) {
        this.initializeDraftAllocations();
      }
    });
  }

  ngOnDestroy() {
    this.onDestroy$.next(true);
    this.onDestroy$.complete();
  }
Run Code Online (Sandbox Code Playgroud)

何时/如何退订的主题在此处进行了广泛讨论:Angular / RxJs我何时应该退订`Subscription`


ape*_*hev 5

只是为了澄清 - 你不需要销毁Observables,只需要销毁订阅.

似乎其他人已经指出您现在也可以使用ngOnDestroy服务.链接:https://angular.io/api/core/OnDestroy

  • 您能详细说明一下吗 (2认同)