【问题标题】:Destroy Angular 5 components when move to another menu移动到另一个菜单时销毁 Angular 5 组件
【发布时间】:2018-09-19 06:33:36
【问题描述】:

我有一个报告组件,它订阅了行为主题,它在 .next 调用之后从 web api 中提取数据。 当我在报告页面后移动到另一个页面时,报告组件仍然存在并不断向 webApi 发送调用。

导航到另一个或取消订阅行为主题后如何销毁组件。 更多细节。 我的报表组件很少,它呈现不同类型的报表。其中一个组件在下面

@destroyAllSubscribers()
    export class StandardReportComponent implements OnInit {

    public subscriptions: Subscription[] = [];
    reportData = [];
    showReport=false;
    constructor(private reportService: ReportService)
    {

        this.subscriptions.push(this.reportService.chartType.subscribe(chartType => {

        if (this.currentChart != ReportChartType.None){

         this.showReport=false;  //Used in *ngIf to show report HTML template
            this.reportService.getReportData().subscribe(result=>{
        this.reportData=result; 
        this.showReport=true; //Used in *ngIf to show report HTML template


    }

    }

    }
    }

我有销毁订阅者装饰器,它会在组件销毁时执行,

代码:

export function destroyAllSubscribers() {
    return (targetComponent: any) => {
      targetComponent.prototype.ngOnDestroy = ngOnDestroyDecorator();

      function ngOnDestroyDecorator() {
        return function () {
          if (this.subscriptions != undefined)
          {
            this.subscriptions.forEach(subscription => {
              if (subscription instanceof Subscriber) {
                subscription.unsubscribe();
              };
            });
          }
        };
      }
    };
}

它应该取消订阅;但是所有订阅也会在导航到其他页面后执行。

【问题讨论】:

  • 请为您的ReportComponent 发布一些代码以使其清楚。
  • export class ReportComponent { constructor(private reportService: ReportService) this.chartService.currentDates.subscribe(date => { //从web API获取数据 }); } }
  • 我已经粘贴了示例代码,希望对您有帮助

标签: angular angular5 behaviorsubject


【解决方案1】:

您可以像这样使用 OnDestroy 生命周期挂钩在页面销毁时取消订阅行为主题

this.sub_State = this.stateService.showStateBehaviorSubject.subscribe((state: boolean) => {
            this.showState = state;
        });
ngOnDestroy() {
        this.sub_State .unsubscribe();
    }

【讨论】:

  • 谢谢,我试过了;但是它不起作用
【解决方案2】:

创建一个 Subject 属性并获取订阅,直到它在 ngDestroy 中被销毁

class MyComponent {
  destroyed$ = new Subject();

  ngOnDestroy() {
    this.destroyed$.next();
  }

  myMethod() {
   this.apiHelper.get('some/url')
     .pipe( takeUntil(this.destroyed$) )
     .subscribe(()=> {
       // do things
     });
  }
}

【讨论】:

    【解决方案3】:

    只需使用async 管道即可在模板上显示数据,而无需订阅 BehaviorSubject。

    this.data$ = this.reportService.behaviourSubjectObj
    

    在您的模板中:

    {{ data$ | async | json }}
    

    【讨论】:

    • 这不会关闭订阅。它还限制了您可以做的事情,例如,如果您必须在组件中映射数据或存储属性,这也不允许您这样做。
    • 没有人阻止他在组件中的 behaviorSubjectObj 上调用 map。你确定第一点?
    • 我猜你是对的,暂时忘记了运算符。我的错。
    【解决方案4】:

    使用 ComphonentRef ,如果要从父级销毁它,请按照以下代码进行操作

    @ViewChild(ChildComponent, { read: ComponentRef }) childComponentRef: ComponentRef;

    电话

    this.childComponentRef.destroy()

    在 parent 事件中起作用。

    参考这个link

    【讨论】:

      猜你喜欢
      • 2019-10-04
      • 1970-01-01
      • 2020-07-18
      • 2021-04-26
      • 1970-01-01
      • 2018-12-17
      • 2016-12-05
      • 2019-07-28
      • 2017-03-20
      相关资源
      最近更新 更多