I am new to angular 4. What I'm trying to achieve is to set different layout headers and footers for different pages in my app. I have three different cases:
routes: ['login','register']
routes : ['','about','contact']
routes : ['dashboard','profile']
I run the app temporarily by adding a header and footer to my router component html.
Please advise me a better approach.
This is my code:
const appRoutes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'about', component: AboutComponent},
{ path: 'contact', component: ContactComponent},
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'profile', component: ProfileComponent },
// otherwise redirect to home
{ path: '**', redirectTo: '' }
];
export const routing = RouterModule.forRoot(appRoutes);
<router-outlet></router-outlet>
<site-header></site-header>
<div class="container">
<p>Here goes my home html</p>
</div>
<site-footer></site-footer>
<site-header></site-header>
<div class="container">
<p>Here goes my about html</p>
</div>
<site-footer></site-footer>
<div class="login-container">
<p>Here goes my login html</p>
</div>
<app-header></app-header>
<div class="container">
<p>Here goes my dashboard html</p>
</div>
<app-footer></app-footer>
I saw this question on stack-overflow but i didn't get a clear picture from that answer
You can solve your problem using child routes.
See working demo at https://angular-multi-layout-example.stackblitz.io/ or edit at https://stackblitz.com/edit/angular-multi-layout-example
Set your route like below
const appRoutes: Routes = [
// Site routes goes here
{
path: '',
component: SiteLayoutComponent,
children: [
{ path: '', component: HomeComponent, pathMatch: 'full'},
{ path: 'about', component: AboutComponent }
]
},
// App routes goes here
{
path: '',
component: AppLayoutComponent,
children: [
{ path: 'dashboard', component: DashboardComponent },
{ path: 'profile', component: ProfileComponent }
]
},
// no layout routes
{ path: 'login', component: LoginComponent},
{ path: 'register', component: RegisterComponent },
// otherwise redirect to home
{ path: '**', redirectTo: '' }
];
export const routing = RouterModule.forRoot(appRoutes);
you can use child e.g.
const appRoutes: Routes = [
{ path: '', component: MainComponent,
children:{
{ path: 'home' component:HomeComponent},
{ path: 'about', component: AboutComponent},
{ path: 'contact', component: ContactComponent},
..others that share the same footer and header...
}
},
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'admin', component:AdminComponent,
children{
{ path: 'dashboard', component: DashboardComponent },
{ path: 'profile', component: ProfileComponent }
..others that share the same footer and header...
}
}
{ path: '**', redirectTo: '' }
];
MainComponent and AdminComponent like
<app-header-main></app-header-main>
<router-outlet></router-outlet>
<app-footer-main></app-footer-main>
the post talk about separate in diferent files the routes
There are cases where the layout and shared elements don't really match the routing structure, or some elements have to be hidden/shown depending on a per-route basis. For such cases I can think of the following strategies (let's take an example of app-header-main
component - but it will apply to any shared page element obviously):
You can provide inputs or css classes to control the inner appearance of your shared elements, such as:
<app-header-main [showUserTools]="false"></app-header-main>
or
<app-header-main class="no-user-tools"></app-header-main>
and then use :host(.no-user-tools) to show/hide what needs to beor
at a route level (child or not):
{
path: 'home',
component: HomeComponent,
data: {
header: {showUserTools: true},
},
},
And access it through ActivatedRoute
like so: this.route.data.header.showUserTools
Inside app-header-main
component:
@Input() rightSide: TemplateRef<any>;
Input of type TemplateRef<any>
where you could feed an ng-template
element directly
<app-header-main [rightSide]="rightside"></app-header-main>
<ng-template #rightside>your content here</ng-template>
You can author the app-header-main so that it uses named slot transclusion
Inside of app-header-main template:
<ng-content select="[rightSide]"><ng-content>
Usage:
<app-header-main class="no-user-tools">
<div rightSide>your content here</div>
</app-header-main>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With