Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nesting Angular2 RC5 Routes Multiple Files

I'm trying to understand how I'm supposed to organize multiple routing files and make them all play nicely together.

My desired routes look like this:

/
/forms
/forms/:id
/forms/named-form (named-form2, named-form3, etc.)
/forms/named-form(2,3,etc)/admin
/forms/named-form(2,3,etc)/admin/(several options here)

My desired file organization:

/app.module
/app.routes
/app.component <--Router Outlet

/forms/forms.module
/forms/forms.routes
/forms/forms.component <--Router Outlet for displaying Form Creation, Details, Settings, etc.

/forms/named-form/named-form.module
/forms/named-form/named-form.routes
/forms/named-form/named-form.component <--Router Outlet for displaying Form or Admin section

/forms/named-form/admin/admin.module
/forms/named-form/admin/admin.routing
/forms/named-form/admin/admin.component <--Router Outlet for various admin pages    

The way I have things now:

/forms.routing.ts

const formsRoutes: Routes = [
  {
    path: 'forms',
    component: FormsComponent,
    children: [
      { path: '', component: FormsListComponent },
      { path: ':id', component: FormsListComponent }
    ]
  }
];

export const formsRouting = RouterModule.forChild(formsRoutes);

/forms/named-form.routing.ts

const namedFormRoutes: Routes = [
  {
    path: 'forms/named-form',
    component: NamedFormComponent,
    children: [
      {
        path: '',
        component: NamedFormFormComponent,
      },
      {
        path: 'confirmation',
        component: NamedFormConfirmationComponent
      }
    ]
  }
];

/forms/named-form/admin.routes.ts

const namedFormAdminRoutes: Routes = [
  {
    path: 'forms/named-form/admin',
    component: NamedFormAdminComponent,
    children: [
      {
        path: '',
        component: ManageDataComponent,
      },
       {
         path: 'manage-data',
         component: ManageDataComponent
        },
       {
        path: 'settings',
        component: SettingsComponent
      },
      {
        path: 'import',
        component: ImportDataComponent
      }
    ]
  }
];

This mostly works but there are a few problems I have with it. I wish I didn't have to specify the full paths the deeper I go in the nested routes. For instance the admin path is forms/named-form/admin but I'd like it to already know it's a child of named-form. This is one of the things that leads me to think I'm doing something wrong.

I also need to be able to do things in my named-form.component file that will effect the admin.component but the named-form.component doesn't currently get touched if I navigate to forms/named-form/admin. It ends up using the primary app.component router-outlet instead of the named-form.component router-outlet. I can include a path for admin inside the named-form.routes file but then I don't know how to setup the admin children routes without also having to import all the main admin child components as well which makes it less modular.

I'm not sure if seeing my modules is necessary, but if so I'll add them in.

How can I do this better? Thanks for looking.

like image 204
andyrue Avatar asked Aug 24 '16 19:08

andyrue


2 Answers

From what I've seen there is currently(RC5) no simple way to setup routes with nested modules. I've implemented a solution described in this Stack Overflow answer:

How to route to a Module as a child of a Module - Angular 2 RC 5

It uses a hybrid of the pre-RC5 routing (exporting the Routes object instead of RouterModule.forChild) and the current RC5 ngModule setup. Unfortunately it forces you to list the child router component in your parent route config and export ALL components within the child module which obviously is not ideal. But at least you do not have to use the full route path in your child route configs as you have in your example. Also this setup is properly nesting the router-outlets and not reverting to the root router-outlet as you mentioned above.

Some snippets of my configuration:

// parent route config
const routes: Routes = [
{
    path: '',
    redirectTo: '/home',
    pathMatch: 'full'
},
{
    path: '',
    component: BaseComponent,
    canActivate: [AuthGuard],
    children: [
        { path: 'home', component: HomeComponent },            
        {
            path: 'admin',
            children: [...adminRoutes]             
        }            
    ]        
}    
];


// child route config (for me, "/admin")
export const adminRoutes: Routes = [
{
    path: '',
    component: AdminComponent,
    children: [
        {
            path: '',
            redirectTo: 'client-list',
            pathMatch: 'full'
        },
        { path: 'client-list', component: AdminClientListComponent, canActivate: [AdminClientListGuard] },
        { path: 'list', component: AdminListComponent },
        { path: 'edit/:id', component: AdminEditComponent }
    ]
}
];
like image 89
cboston Avatar answered Oct 21 '22 18:10

cboston


I answered this question at the mentioned How to route to a Module as a child of a Module - Angular 2 RC 5 article. Here is a copy of my answer:

When you are using ngModules and RC5, the routing configuration of your parent module does not need to know anything about the child modules routing. You only have to define the routes for your parent module here. Furthermore you have to import the child module into your parent module. In the child module you have to define your routes this way:

export const childRoutes: Routes = [
  {
    path: 'someChild',
      component: SomeChildComponent,
      children: [
        { path: '', component: SomeChildSubComponent1 },
        { path: 'comp1', component: SomeChildSubComponent1 },
        { path: 'comp2', component: SomeChildSubComponent2 }
      ]
  }
];

This will let you have a url like /someParent/someChild/comp1 - and the components are displayed in their corresponding router-outlet. Please note: You HAVE TO declace a component for the empty path. Otherwise you are not able to navigate to you children.

like image 21
westor Avatar answered Oct 21 '22 17:10

westor