3
votes

I have a problem with Angular routing. I have main app routing module and sub module with its own routing module and router-outlet but routes defined in this submodule are shown using root router outlet and not the child one.

My folder structure:

My code listings

app-routing.module.ts

const routes: Routes = [
  { path: '', component: HomeComponent, pathMatch: 'full' }
];

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

app.component.html

<router-outlet></router-outlet>

home-routing.module.ts

const routes: Routes = [
  { path: '', component: LandingPageComponent},
  { path: 'register', component: RegisterComponent },
  { path: 'login', component: LoginComponent }
];

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

home.component.html

...
<div class="inner cover">
  <router-outlet></router-outlet>
</div>
...

That's what I get when I use empty path - it opens home component properly.

enter image description here

But when i enter /register i get plain html from login.component.html without template in home.component.html file

enter image description here

EDIT

I added name to child outlet

<router-outlet name="home"></router-outlet>

Changed route names to:

const routes: Routes = [
  { path: '', component: LandingPageComponent, outlet: 'home'},
  { path: 'register', component: RegisterComponent, outlet: 'home' },
  { path: 'login', component: LoginComponent, outlet: 'home' }
];

Now I got that error:

enter image description here

EDIT 2

I try to access those routes in 2 ways: A link(which may be incorrect):

<a routerLink="/login">Log In</a></li>

Or typing manually:

localhost:4200/login
3
In home-routing add children: [ { ...} ] inside the routes where you define the routes childalehn96

3 Answers

1
votes

In Angular 2, router outlets can be named:

<router-outlet>
    <router-outlet name="children"></router-outlet>
</router-outlet>

App:

const routes: Routes = [
  { path: '', component: HomeComponent, pathMatch: 'full' }
];

Home:

const routes: Routes = [
  { path: '', component: LandingPageComponent, outlet: 'children'},
  { path: 'register', component: RegisterComponent, outlet: 'children' },
  { path: 'login', component: LoginComponent, outlet: 'children' }
];

You can even define child routes:

const routes: Routes = [
  { path: '', 
    component: HomeComponent, 
    pathMatch: 'full', children: [
      { path: '', component: LandingPageComponent, outlet: 'children'},
      { path: 'register', component: RegisterComponent, outlet: 'children' },
      { path: 'login', component: LoginComponent, outlet: 'children' }
    ] 
   }
];

http://onehungrymind.com/named-router-outlets-in-angular-2/

0
votes

If you want those 3 components to be rendered inside of the HomeComponent in a named outlet, then you need to define the following routes:

const routes: Routes = [
  { path: '', 
    component: HomeComponent, 
    pathMatch: 'full'
   },
   { path: 'landing', component: LandingPageComponent, outlet: 'children'},
      { path: 'register', component: RegisterComponent, outlet: 'children' },
      { path: 'login', component: LoginComponent, outlet: 'children' }
];

And inside of app.component.html add the named router outlet

....//html template 
<router-outlet name="children"></router-outlet>
....//html template

EDIT 1:

To navigate to the named outlets you need to use the following routed links:

//inside of home.component.html
 <a [routerLink]="[{ outlets: { children: ['login'] } }]">Take me to login!</a>

The generated link will look like:

root/(children:login)

More info in the following link to the docs

EDIT 2:

I changed the original routes and the component template where the named outlet is added. Why?

it is not possible, as far as I know, to have a named outlet with an empty path (''). The empty path tells angular that the named outlet is empty (no component is currently rendered in it).

0
votes

I believe your problem has to do with declarations. I can not know for certain since you didn't show the code in your app.module.ts and home.module.ts file and have not tested this fully myself.

A component needs to be declared inside the module connected to the template with the desired routing outlet. In your case the login component would need to be added to "declarations" in your home.module.ts file and removed from "declarations" in the app.module.ts file.

Angular does not seem allow you to reuse the same component in multiple routing-outlets unless they are in the same template, since it would cause an error stating "x component declared in multiple modules".