Angular 5: how do I route all paths to reach a single component using only one route?

My current configuration:

const routes: Routes = [ { path: '', component: NavComponent, outlet: 'nav' }, // (1) { path: '**', component: NavComponent, outlet: 'nav' } // (2) ]; 

It works. NavComponent always displayed on nav output. In particular, it works for all of the following types of URLs:

 http://example.com/foo(nav:bar) // (a) non-empty path in nav --> (2) http://example.com/foo(nav:) // (b) empty path in nav --> (2) http://example.com/foo // (c) no nav at all --> (1) 

Note that the router maps different routes to these URLs:

  • (1) used for (c)
  • (2) used for (a) and (b)

This is why the NavComponent instance NavComponent destroyed and recreated every time location changes say (c) to (a) . And this is what I need to prevent. I need to save my instance due to its state, animation, etc. As far as I understand, this is possible only if the same route is used for all URLs, however I cannot find a way to do this. If I remove (1) , URLs such as (c) will stop showing NavComponent in nav . Apparently ** does not match such URLs (I'm not sure why).

You can see it in action here: https://stackblitz.com/edit/angular-ptzwrm

What is the right solution here?

I am currently redefining UrlSerializer to add (nav:) to URLs like (c) before parsing, but this seems like a hack.

+8
angular angular-router
source share
2 answers

Stupid question, but can you just change the URL using the location service and stay on one component (and just change the states for your animations)?

Otherwise, you can implement a custom RouteReuseStrategy to force reuse of your component

 import { RouteReuseStrategy } from '@angular/router'; import {ActivatedRouteSnapshot} from '@angular/router'; import { DetachedRouteHandle } from '@angular/router'; /** Use defaults from angular internals, apart from shouldReuseRoute **/ export class CustomReuseStrategy implements RouteReuseStrategy { shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; } store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {} shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; } retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle|null { return null; } shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { let name = future.component && (<any>future.component).name; return future.routeConfig === curr.routeConfig || name == "NavComponent"; } } @NgModule({ providers: [ { provide: RouteReuseStrategy, useClass: CustomReuseStrategy }] }) export class AppModule { } 

Here is your modified stackblitz that will always use NavComponent

https://stackblitz.com/edit/angular-tj5nrm?file=app/app.module.ts

References

Reuse route. The strategy is explained: https://medium.com/@gerasimov.pk/how-to-reuse-rendered-component-in-angular-2-3-with-routereusestrategy-64628e1ca3eb

The default values ​​for the angular router strategy are: https://github.com/angular/angular/blob/master/packages/router/src/route_reuse_strategy.ts

+3
source share

I mean, you need a router socket. Something like that:

app.component.html: <router-outlet></router-outlet>

Function-area.component.html: <your-navbar-component></your-navbarcomponent> <router-outlet></router-outlet>

child-of-function-area.component.html: < h1>Hi there!</h1>

your-Navbar-component.component.html: < p>some links here...</p>

When accessing http://localhost:4200/feature-path/child-feature-path you will get:

some links here ...

Hello!

If you need, I can write a puker with an example to better explain. But I mean that you are overloading the router with a task that may not be for him.

0
source share

All Articles