问题
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