Angular2+ routeReuseStrategy lifecycle hooks

爷,独闯天下 提交于 2019-12-21 11:27:18

问题


I'm trying to take advantage of a custom RouteReuseStrategy and for that I'd like to suspend any subscriptions when a component is detached and other things like scrolling to the proper position.

I've checked for possible hooks, but apparently no additional lifecycle hooks have been added and OnDestroy isn't called.

I tried to add my own onDetach and onAttach hooks, but neither the ActivatedRouteSnapshots nor the DetachedRouteHandle will give me the instance of the current component (just the prototype?).

The only way I could get a grip on the component instance when navigating away by using the CanDeactivate guard, but that doesn't seem right. And I still couldn't find a way to add a hook for onAttach.

So my question is, how can I properly suspend a component when detached and resume it when attached ?

There used to be a OnActivate hook-interface in @angular/router, but that seems to be gone and I didn't see any replacement.

P.S. there seem to some reports of Angular apps with custom RouteReuseStrategies slowing down when used for extended time, probably because there is no way to pause/resume components.


回答1:


I fixed it (yes this is more a bug than a missing feature).

Extend RouterOutlet and override attach() and detach() (see below), then replace your <router-outlet> tags with <app-router-outlet>. If your component has a onDetach and/or onAttach(ref: ComponentRef<any>, activatedRoute: ActivatedRoute) method, it will be called.

import {ComponentRef, Directive} from '@angular/core';
import {ActivatedRoute, RouterOutlet} from '@angular/router';

@Directive({
  selector: 'app-router-outlet',
})
export class AppRouterOutletDirective extends RouterOutlet {

  detach(): ComponentRef<any> {
    const instance: any = this.component;
    if (instance && typeof instance.onDetach === 'function') {
      instance.onDetach();
    }
    return super.detach();
  }

  attach(ref: ComponentRef<any>, activatedRoute: ActivatedRoute): void {
    super.attach(ref, activatedRoute);
    if (ref.instance && typeof ref.instance.onAttach === 'function') {
      ref.instance.onAttach(ref, activatedRoute);
    }
  }
}

P.S. Even with that fix custom RouteReuseStrategies are still pretty useless, without access to history states or preserved data in the ActivatedRoute there is no way of identifying two instances with the same routeConfig/path.

Paired with some weird timing of angular's calls to RouteReuseStrategy, Router Navigation Events and history.pushState it's extremely hard to write workarounds for that.

This is extremely frustrating to work with.



来源:https://stackoverflow.com/questions/46519512/angular2-routereusestrategy-lifecycle-hooks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!