简体   繁体   中英

Angular navigate directly to lazy loaded module child route

I have an Angular module lazy loaded called example.module. In example.module I have two different components called a.component and b.component and a bunch of different sub components both a and b use.

What I would like is that when the module is lazy loaded from the router I can route directly to either one of those two components based on which route the user selected from the parent routing.

The only work around I can think of is making two entirely separate modules each of which is lazy loaded independently with the common code being in a third shared module imported by the two. That seems like a lot more templated code and files I need to produce across my entire application rather then there being some way I can signal to a lazyloaded component to load one of the routes programmatically.

        RouterModule.forChild(
        [
          {
            path: "",
            redirectTo: "component-a" // How do I go to A or B?
          },
          {
            path: "component-a",
            component: ComponentA
          },
          {
            path: "component-b",
            component: ComponentB
          },
        ]

Thanks for your assistance and knowledge on the topic!

Edit - As requested root routing.

const appRoutes: Routes = [
  {
    path: "example",
    loadChildren: "./example.module#ExampleModule",
  },
];

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

Plunk - https://embed.plnkr.co/uiLFu0EBZ00F8sLH836w/

When working with lazy loaded modules you should treat them as eagerly loaded modules and the routes configuration you specify in the .forChild(routes) is merged into the single application wide configuration.

So in your particular case you define in the forRoot :

export const routes: Routes = [
  { path: 'crisis-a', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
  { path: 'crisis-b', loadChildren: 'app/crisis/crisis.module#CrisisModule' }
];

and in the .forChild()

const routes: Routes = [
  { path: 'crisis-a',    component: CrisisListComponentA },
  { path: 'crisis-b',    component: CrisisListComponentB },
];

So once merged you will have the following configuration:

export const routes: Routes = [
  { 
    path: 'crisis-a', 
    children: [
        { path: 'crisis-a',    component: CrisisListComponentA },
        { path: 'crisis-b',    component: CrisisListComponentB }
    ]
  { 
    path: 'crisis-b', 
    children: [
        { path: 'crisis-a',    component: CrisisListComponentA },
        { path: 'crisis-b',    component: CrisisListComponentB }
    ]
  }
];

Hence if you want to navigate to CrisisListComponentB with /crisis-b you have to specify full URL

/crisis-b/crisis-b

I would make a canActivate guard to route them appropriately once the module is resolved.

Update the routes to be:

RouterModule.forChild(
[
  {
    path: "",
    canActivate: [RootRouteGuard]
  },
  {
    path: "component-a",
    component: ComponentA
  },
  {
    path: "component-b",
    component: ComponentB
  },
]

And then the guard would look something like this:

@Injectable()
export class RootRouteGuard implements CanActivate {

  constructor(private router: Router) {}

  public canActivate(route: ActivatedRouteSnapshot) {
    if (/* Logic */) {
      this.router.navigateByUrl('component-a');
    } else {
      this.router.navigateByUrl('component-b');
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM