Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2+ routeReuseStrategy lifecycle hooks

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.

like image 973
Su-Au Hwang Avatar asked Oct 02 '17 04:10

Su-Au Hwang


People also ask

What is the lifecycle hooks in angular?

Lifecycle hooks link A component instance has a lifecycle that starts when Angular instantiates the component class and renders the component view along with its child views. The lifecycle continues with change detection, as Angular checks to see when data-bound properties change, and updates both the view and the component instance as needed.

Do all lifecycle methods need to be implemented in angular?

There are a few who only execute once after component initialization. All lifecycle methods are available from @angular/core. Although not required, Angular recommends implementing every hook. This practice leads to better error messages regarding the component.

How do I respond to events in the angular lifecycle?

Respond to events in the lifecycle of a component or directive by implementing one or more of the lifecycle hook interfaces in the Angular core library. The hooks give you the opportunity to act on a component or directive instance at the appropriate moment, as Angular creates, updates, or destroys that instance.

How do I use hook methods in angular?

After your application instantiates a component or directive by calling its constructor, Angular calls the hook methods that you have invoked at the appropriate point in that instance's lifecycle. Angular executes hook methods in the following order. You can use it to perform the following types of tasks.


Video Answer


1 Answers

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.

like image 143
Su-Au Hwang Avatar answered Sep 21 '22 11:09

Su-Au Hwang