Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using child routing in the same router outlet as parent(s)

I want to be able to use the same router-outlet for some routes.

Routing setup (simplified):

export const routes: Routes = [
    {
        path: 'app', component: AppComponent,
            children: [
                path: 'category/:id', component: CategoryComponent,
                children: [
                    { path: 'post/:id', component: PostComponent }
                ]
            ]
    }
];

For example we have this path:

/app/category/1/post/1

That breaks into

/app - AppComponent
|_ /catory/1 - CategoryComponent
   |_/post/1 - PostComponent

The AppComponent has a <router-outlet> which renders CategoryComponent, but should also render the PostComponent when that route is active.

Common answers for this type of question:

Move the child routes and add them in the app-route children array

No. This isn't the right way. We still want our hierarchy of routes. CategoryComponent may know something which PostComponent doesn't - Such as Breadcrumb naming

So we still want our CategoryComponent to load. (Even if it's view isn't renders)

Use a <router-outlet> inside of CategoryComponent

No. The CategoryComponent should not be in charge of it's own <router-outlet>. The PostComponent should be rendered in place of the CategoryComponent, and add CSS to place it like that should be illegal.

How can I acheive this behaviour?

Do i need to write my own router-outlet?

Will this be solved in Angular4?

Any tips are welcome! Thanks

like image 210
Marcus Brunsten Avatar asked Jan 25 '17 12:01

Marcus Brunsten


1 Answers

Since we're meanwhile at Angular 7 and there seems to be no documentation for this, I guess that there is no simple out-of-the box solution for the problem.

I had a very similar problem: The child route of a lazy loaded module should be rendered inside the app component's outlet and not inside an outlet of the lazy loaded module. I'm working with lazy loaded modules but you probably can transform this idea to your use case. I was able to solve the issue by defining the according route on the expected outlet level, meaning inside the AppRoutes (I think there is no other way):

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: 'category/:cid',
    loadChildren: './category/category.module#CategoryModule',
  },
  {
    path: 'category/:cid/post/:pid',
    loadChildren: './category/post/post.module#PostModule'
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

This way I can at least guarantee the folder structure and URL hierarchy remain the way I want them to be. In order to solve the state management problem you mentioned, I would deserialize data about categories inside the PostComponent or PostRoute. However, this would introduce some maybe unwanted redundancy.

To me this is far from ideal, because I'm not able to encapsulate things inside lazy loaded modules the way I want. But: it's working.

like image 57
Robert Avatar answered Sep 23 '22 10:09

Robert