Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 5: how do I route all paths for an outlet to the same component using only 1 route?

My current configuration:

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

It works. NavComponent is always rendered to the outlet nav. In particular, it works for all the following kinds 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)

Notice that the router matches different routes to these URLs:

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

That is why the NavComponent instance is destroyed and recreated every time the location changes say from (c) to (a). And that's something I need to prevent. I need to keep my instance because of its state, animations, etc. As far as I understand, it's possible only if the same route is used for all the URLs, however I can't find a way to do this. If I remove (1), the URLs like (c) stop showing NavComponent in nav. Apparently ** doesn't match such URLs (I'm not sure why though).

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

What is the proper solution here?

For now, I'm overriding UrlSerializer to add (nav:) to URLs like (c) before parsing, but it feels like a hack.

like image 743
thorn0 Avatar asked Feb 12 '18 10:02

thorn0


People also ask

Can we define multiple router outlets in a component view?

You can have multiple router-outlet in same template by configuring your router and providing name to your router-outlet, you can achieve this as follows. Advantage of below approach is thats you can avoid dirty looking URL with it. eg: /home(aux:login) etc.

Can we have multiple routes in Angular?

Angular Router supports multiple outlets in the same application. A component has one associated primary route and can have auxiliary routes. Auxiliary routes enable developers to navigate multiple routes at the same time.

Which is used to match paths that are not part of defined routes?

The path can take a wildcard string (**). The router will select this route if the requested URL doesn't match any paths for the defined routes. This can be used for displaying a “Not Found page” view or redirecting to a specific view if no match is found.

What is dynamic routing in Angular?

By Rob Gravelle. February 11, 2022. As the name suggests, the primary purpose of Angular Route Guards is to guard access to a certain route, such as an authenticated area of your app, or an admin section that requires special permissions to be accessed.


1 Answers

Dumb question, but can you not simply modify the URL using location service and stay on the same component (and just change states for your animations)?

Otherwise, you can implement a custom RouteReuseStrategy to force reusing 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, which will always reuse your NavComponent

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

Links

Route reuse Strategy explained: https://medium.com/@gerasimov.pk/how-to-reuse-rendered-component-in-angular-2-3-with-routereusestrategy-64628e1ca3eb

Default values for angular router strategy: https://github.com/angular/angular/blob/master/packages/router/src/route_reuse_strategy.ts

like image 181
David Avatar answered Oct 10 '22 21:10

David