Angular 2 lazily loaded routes that contain aux ro

2020-02-13 05:29发布

问题:

I'm having an issue with my routing that I'd need a little help with. Originally I had all my routing in a single app.routing.ts file. I'm currently refactoring my routes into a files to accompany their corresponding feature modules to be lazily loaded. One lazily loaded feature module utilizes a secondary aux router outlet. Here is my code....

original : app.routing.ts

const appRoutes: Routes = [
    {
        path: 'settings',
        component: SettingsComponent,
        children: [
          {
            path: '',
            redirectTo: '/settings/(settings:user)',
            pathMatch: 'full'
          },
          {
            path: 'user',
            component: SettingsUserComponent,
            outlet: 'settings'
          }
        ]
    }
]

new: app.routing.ts

const appRoutes: Routes = [
  ...
  {
      path: 'settings',
      loadChildren: '@app/settings/settings.module#SettingsModule'
  }
  ...
]

settings.routing.ts

export const SETTINGS_ROUTES = [
    {
        path: '',
        redirectTo: '/settings/(settings:user)',
        pathMatch: 'full'
    },
    {
        path: 'user',
        component: SettingsUserComponent,
        outlet: 'settings'
    }
]

So the issue is that originally my settings path would load the SettingsComponent that contains the settings outlet. The empty child path would then redirect to /settings/(settings:user) and load the SettingsUserComponent in the settings aux router outlet.

Now that I've refactored, there is no SettingsComponent being loaded so an error occurs saying that there is not a settings outlet.

From the documentation, it states that I'm not able to use component attribute with loadChildren. I can't use component with redirectTo in the SETTINGS_ROUTES either. I've tried wrapping my settings routes in another empty path like below but didn't seem to solve the problem.

settings.routing.ts

export const SETTINGS_ROUTES = [
    {
        path: '',
        component: 'SettingsComponent',
        children: [
            {
                path: '',
                redirectTo: '/settings/(settings:user)',
                pathMatch: 'full'
            },
            {
                path: 'user',
                component: SettingsUserComponent,
                outlet: 'settings'
            }
        ]
    }
]

How do I go about loading my SettingsComponent that contains the settings outlet for the child routes. Any suggestions are greatly appreciated.

Thanks

Update

https://github.com/angular/angular/issues/10981#issuecomment-301787482

There is an issue for this since Aug 2016. Some have been able to create workarounds with Angular4. I've tried them but don't seem to work properly with Angular2.

If anyone has a successful workaround for Angular2, I'd appreciate if you'd post them.

回答1:

Just an update to provide a solution to this problem. After reading through the issue reported on github, Keith Gillette's solutions works after I fiddled around with it a bit.

https://github.com/angular/angular/issues/10981#issuecomment-301787482


Solution:

The way that I constructed my routes are as follows:

  1. Initial empty path with no component declared.
  2. You will then declare child routes on this empty path with all your sub paths.
  3. The sub paths declare the path and the base component that contains your aux router outlet. In my case the SettingsComponent contains my settings router outlet.
  4. Each sub path will then declare another set of children containing an empty path with the component to be loaded in the aux router outlet.

Below is an example of my routes that are working.

app.routing.ts (stays the same)

const appRoutes: Routes = [
  {
    path: 'schedule',
    loadChildren: '@app/schedule/schedule.module#ScheduleModule'
  }
];

settings.routing.ts

export const SETTINGS_ROUTES = [
  {
    path: '',
    children: [
      {
        path: 'schedule',
        component: SettingsComponent,
        children: [
          {
            path: '',
            component: SettingsScheduleComponent,
            outlet: 'settings'
          }
        ]
      },
      {
        path: 'user',
        component: SettingsComponent,
        children: [
          {
            path: '',
            component: SettingsUserComponent,
            outlet: 'settings'
          }
        ]
      }
    ]
  }
];

Note:

One thing to note is that the paths no longer follow the aux router path pattern.

Aux Route Path

<a [routerLink]="['/settings', { outlets: { settings: 'user'} }]">
  User
</a>

New Routing Paths

<a [routerLink]="['/settings/user']">
  User
</a>

Conclusion

This solutions works for my routing. I did not test it for multiple nested child routes though. Reading some of the comments on the above linked github issue, some are reporting that child routes where you declare the component to be loaded in the aux router outlet only seem to work with empty paths. I did not test this. You may need to continue nesting empty router paths with aux routers to workaround this. Hope this helps.