6

I'm creating a Dashboard like application. I'd like to achieve the following layout plan in Angular (2+):

  • route - name - layout
  • / - home page - full width layout with tables and charts, etc
  • /reports - reports page - same full width layout with more tables, etc
  • /login - login page - no full width layout, just a simple login form at screen center
  • /signup - signup page - no full width layout, just a simple signup form at screen center
  • /messages - emails - full width layout
  • /messages/new - new email - medium layout, not inheriting from full width layout

etc...

So basically what I'd like to do is to completely replace the contents of <body> at some (child) routes.

This is not good for me: multiple layout for different pages in angular 2 because I don't want to redirect / (root) to anywhere like /home.

This one doesn't fit either: How to switch layouts in Angular2

Any help would be great!

Community
  • 1
  • 1
papaiatis
  • 4,231
  • 4
  • 26
  • 38

2 Answers2

15

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 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);

Recommended reference: http://www.tech-coder.com/2017/01/multiple-master-pages-in-angular2-and.html

Rameez Rami
  • 5,322
  • 2
  • 29
  • 36
3

Ok I am going to give this a shot...

Routes

Creating routes can be done in multiple ways. You can use child routes or serve the component up directly.

If you want to serve the component up directly this would be ideal,

{ path: '*pathInURL*', component: *NameComponent* }

Direct problems you are facing

Three problems,

  1. Show a component as a child.

  2. Show a component in a template called fullwidth

  3. Show a component in a template called mediumwidth

In your routes.ts

const APP_ROUTES: Routes = [
// landing page of your application
    { path: '', redirectTo: '/home', pathMatch: 'full', },
//anything that will be handled in blank template
    { path: '', component: BlankComponent, data: { title: 'blank Views' }, children: BLANK_ROUTES },
//anything that will be handled in fullwidth
    { path: '', component: FullComponent, data: { title: 'full Views' }, children: FULL_ROUTES },
// anything that will be handled in medium width
    { path: '', component: MediumComponent, data:{ title: 'Medium Views' }, children: MEDIUM_ROUTES }
];

This is going to forward all paths in the URL to look to these routes. It will check the routes to see which template it will fall in.

Then create 3 directories.

/blank

/full

/medium

Inside these folders you will keep your component that use each of the mother templates.

So since login is blank. It would be in /blank

/blank/BlankComonent.ts

Also in each of these directories you will create a routes file which is referred to in the initial routes file we have already created.

/blank/blank.routes.ts

export const BLANK_ROUTES: Routes = [
    { path: 'login', component: LoginComponent }
];

Then in medium the same thing,

/blank/blank.routes.ts

export const MEDIUM_ROUTES: Routes = [
    { path: 'Some/Path', component: SomeMediumComponent }
];

And then the same for FULL_ROUTES

Make a routes file for each directory we created. Add all your routes that live in the same directory and will share the same mother template.

Then we will create a templates directory. Call it /layouts

Now in that direcotry this is where you will create

BlankComponent.ts FullComponent.ts MediumComponent.ts

Each of these components will have their corresponding routes served inside of these templates. Because remember our first routes file says that we will serve all Child Routes to these templates.

So the layouts will be served to the router-outlet

import { Component } from '@angular/core';

@Component({
    selector: 'body',
    template: '<router-outlet></router-outlet>'
})
export class AppComponent { 
}
wuno
  • 9,547
  • 19
  • 96
  • 180
  • Thank you for your extensive answer! However one of my requirement was not to redirect the root URL to anywhere. In your example you redirect it to /home. – papaiatis Feb 17 '17 at 06:01
  • No, what I am saying is that you set whatever you want the landing page to be like that. That way when the app loads it loads the correct page. So your routes don't load till they get there path called. Besides that if this helped you why would you not accept the answer? Also since you asked on the other question which helped you I would appreciate it if you upvote it too. – wuno Feb 17 '17 at 06:03
  • Okay, give me a working example for this requirement: url: localhost/ full layout, url: localhost/login blank layout. – papaiatis Feb 17 '17 at 19:26
  • I just did. Can you just be very blunt with what you dont know how to do? There is no way I can type all the code you need on here. You are basically asking me to layout your whole project for you on stack overflow. So what I can suggest is why not try to get one part working. Then understand it and work on the next part? – wuno Feb 17 '17 at 19:29
  • You did not. Also, I told you already what's not working. Look. I appreciate your help. I'm trying to make this work for hours. I tried your code several times but _again_, it does not work without redirecting the root path to something! And that's not acceptable. – papaiatis Feb 17 '17 at 19:42
  • But because you were so nice to help, I accept your answer. You do have a great day! – papaiatis Feb 17 '17 at 19:49