Search code examples
angularangular-router

Route reuse strategy recommendations


I am implementing router reuse strategy to reuse a component on multiple routes. The reuse is not because it's the same component but because the user will do a lot of interactions with it, and I need to preserve all the states, data, etc.

While a component is detached it still receives events that it has been subscribed to. I am not sure it would work to my advantage, can someone who has used that technology recommend whether having the subscribed events firing while the component is detached are received by a component is a good/bad idea?


Solution

  • I think you need to monitor the router events and then update a flag based on whether you are on the current route. I use a recursive function to construct the URL relative to root, then I compare it with the full URL to find out if the component is active. Then we can use the rxjs operator takeWhile to filter out your events when the component is inactive.

    As far as opinion wise, I would just refresh the page when the back button is pressed, because all of this justs adds complexity to your angular application. You can store the state on the data object and reload the component and populate the same data, which is also feasible.

    import { Component, OnInit } from '@angular/core';
    import { NavigationEnd } from '@angular/router';
    import { ActivatedRouteSnapshot } from '@angular/router';
    import { ActivatedRoute } from '@angular/router';
    import { Router } from '@angular/router';
    import { interval, of } from 'rxjs';
    import { filter, takeWhile } from 'rxjs/operators';
    
    @Component({
      template: `
        Child 3 <input>
      `,
    })
    export class Child3Component implements OnInit {
      isActive: boolean;
      constructor(private router: Router, private activatedRoute: ActivatedRoute) {}
    
      recursiveGetUrl(snapshot: ActivatedRouteSnapshot, output = []) {
        if (snapshot?.routeConfig?.path) {
          output.unshift(snapshot?.routeConfig?.path);
          if (snapshot.parent) {
            output = this.recursiveGetUrl(snapshot.parent, output);
          }
        }
        return output;
      }
    
      ngOnInit() {
        const currentRelativeURL = this.recursiveGetUrl(
          this.activatedRoute.snapshot
        ).join('/');
        this.router.events
          .pipe(filter((event: any) => event instanceof NavigationEnd))
          .subscribe((data: any) => {
            this.isActive = this.router.url.includes(currentRelativeURL);
            console.log(this.isActive, this.router.url, currentRelativeURL);
          });
    
        interval(500)
          .pipe(filter(() => this.isActive))
          .subscribe(console.log);
      }
    }
    

    Stackblitz Demo