Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auxiliary router-outlet inside primary router-outlet

I'm trying to use an auxuliary router-outlet inside the primary router-outlet.

app.routing

export const appRoutes: Routes = [
    { path: '', component: HomeComponent },
    {
        path: 'page',
        loadChildren: () => new Promise(function (resolve) {
            (require as any).ensure([], function (require: any) {
                resolve(require('../pages/page.module').default);
            });
        })
    }
];

app.component

@Component({
    template: `<h1>My App!</h1>
        <a [routerLink]="['/page']">Page</a>
        <router-outlet></router-outlet>`
})

page.module

@NgModule({
    imports: [
        CommonModule,
        RouterModule.forChild([
            {
                path: '',
                component: PageComponent
            },
            {
                path: 'auxpath',
                component: AuxComponent,
                outlet: 'auxoutlet'
            }
        ])
    ],
  declarations: [PageComponent],
  exports: [PageComponent]
})
export default class PageModule {}

page.component

@Component({
    template: `Page <router-outlet name="auxoutlet"></router-outlet>`
})

aux.component

@Component({
    template: `Aux`
})

Error /page/(auxoutlet:auxpath) will see Page component but with this error:

EXCEPTION: Uncaught (in promise): Error: Cannot find the outlet auxoutlet to load 'AuxComponent'
like image 509
Fabrizio De Bortoli Avatar asked Oct 06 '16 10:10

Fabrizio De Bortoli


2 Answers

I tried work with lazy loading and named router-outlets and found the following facts:

  1. auxiliary routes must be children to a parent route with path not being ''. They won't work as children of empty path route. It may be fixed soon.
  2. auxiliary routes are isolated within the parent route. Their matching rule is completely different from standard Angular routing rule.
  3. if we lazy load the module with auxiliary routes, we need to redirect the default empty path route to a route with non-empty path, which has component that holds the named <router-outlet> and its children would be auxiliary routes and other child routes. (It may be fixed soon, same as point 1.)
  4. you can load the named outlet by: url (parentRoute/outletName:['outletPath', param]), or using Router Link directive([routerLink]=['parentRoutes',{outlets: {outletName:['outletPath', param]}}], or programatically (this.router.navigate(['parentRoutes',{outlets: {outletName:['outletPath', param]}}])

  5. To remove a named outlet, specify outlets: {outletName: null} in url, routerLink or code.

  6. Due to a bug(redirect empty path child to named route does not work), there is currently no elegant way to load a named route by default and be able to later remove it with the above method. It may be fixed soon. However, you could have an empty path with a dummy component and in its constructor, you navigate to a URL that loads the default named route. Or you could do it in the parent component.

Special thanks to Brandon

like image 182
Rex Avatar answered Nov 14 '22 22:11

Rex


I resolved using this route configuration:

RouterModule.forChild([
  {
    path: 'wrap',
    component: PageComponent,
    children: [
      {
        path: 'auxpath',
        component: AuxComponent,
        outlet: 'auxoutlet'
      }
    ]
  },

  {
    path: '',
    component: PageComponent
  }
])

This URL works:

/page/wrap/(auxoutlet:auxpath) 
like image 44
Fabrizio De Bortoli Avatar answered Nov 14 '22 22:11

Fabrizio De Bortoli