最好的方法设置不同的布局不同的网页在角度4

我是角度4的新手。我试图实现的是在我的应用程序中为不同的页面设置不同的布局页眉和页脚。我有三个不同的案子:

  1. 登录,注册页面(没有页眉,没有页脚)

路线: [‘ login’,‘ register’]

  1. 营销网站页面(这是根路径,它有一个页眉和页脚,大多数这些部分在登录之前)

路线: [”,‘ about’,‘ contact’]

  1. 应用程序登录页面(我有一个不同的页眉和页脚在这个部分的所有应用程序页面,但这个页眉和页脚是不同的营销网站的页眉和页脚)

路线: [‘ dashboard’,‘ profile’]

我通过在路由器组件 html 中添加一个页眉和页脚来临时运行这个应用程序。

请告诉我一个更好的方法。

这是我的暗号:

应用程序路由

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

App.Component. html

<router-outlet></router-outlet>

App/home/home. Component. html

<site-header></site-header>
<div class="container">
<p>Here goes my home html</p>
</div>
<site-footer></site-footer>

App/about/about. Component. html

<site-header></site-header>
<div class="container">
<p>Here goes my about html</p>
</div>
<site-footer></site-footer>

App/login/login.Component. html

<div class="login-container">
<p>Here goes my login html</p>
</div>

App/dashboard/dashboard.Component. html

<app-header></app-header>
<div class="container">
<p>Here goes my dashboard html</p>
</div>
<app-footer></app-footer>

我看到了 这个问题的堆栈溢出,但我没有得到一个清晰的图片从这个答案

61913 次浏览

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

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

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

Inputs & css classes

You can provide inputs or css classes to control the inner appearance of your shared elements, such as:

  1. <app-header-main [showUserTools]="false"></app-header-main>

or

  1. <app-header-main class="no-user-tools"></app-header-main> and then use :host(.no-user-tools) to show/hide what needs to be

or

  1. 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

TemplateRef input

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>

Named slot transclusion

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>

You can solve the problem using ng-content + ViewChild injection of layout into each page component that uses that specific layout.

Using the router for this common use case always seemed like a workaround to me. What you want is similar to Layouts in Asp.Net MVC or MasterPages in WebForm etc.

After struggling with this I ended up with something like this:

see working demo: https://stackblitz.com/edit/angular-yrul9f

shared.component-layout.ts

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


@Component({
selector: 'shared-component-layout',
template: `
<div *ngIf="!hideLayoutHeader" style="font-size: 2rem;margin-bottom: 10px;">
Layout title: \{\{layoutHeader}}
<ng-content select=".layout-header">
</ng-content>
</div>
<ng-content select=".layout-body">
</ng-content>
`
})
export class SharedComponentLayout {
layoutHeader: string;
hideLayoutHeader: boolean;
}


page.component-base.ts

import { Component, ViewChild } from '@angular/core';
import { SharedComponentLayout } from './shared.component-layout';


export abstract class PageComponentBase {
@ViewChild('layout') protected layout: SharedComponentLayout;
}

login.component.ts - without header

import { Component } from '@angular/core';
import { PageComponentBase } from './page.component-base';


@Component({
selector: 'login-component',
template: `
<shared-component-layout #layout>
<div class="layout-body">
LOGIN BODY
</div>
</shared-component-layout>
`
})
export class LoginComponent extends PageComponentBase {


ngOnInit() {
this.layout.hideLayoutHeader = true;
}
}

home.component.ts - with header

import { Component } from '@angular/core';
import { PageComponentBase } from './page.component-base';


@Component({
selector: 'home-component',
template: `
<shared-component-layout #layout>
<div class="layout-body">
HOME BODY
</div>
</shared-component-layout>
`
})
export class HomeComponent extends PageComponentBase {


ngOnInit() {
this.layout.layoutHeader = 'Home component header';
}
}