web-dev-qa-db-de.com

Beste Methode zum Einstellen eines unterschiedlichen Layouts für verschiedene Seiten in Winkel 4

Ich bin neu bei angle 4. Was ich versuche zu erreichen, ist, unterschiedliche Layout-Kopf- und Fußzeilen für verschiedene Seiten in meiner App festzulegen. Ich habe drei verschiedene Fälle:

  1. Login, Register-Seite (keine Kopfzeile, keine Fußzeile)

routen: ['login', 'register']

  1. Marketing-Site-Seite (dies ist der Stammpfad und hat eine Kopf- und Fußzeile, meistens kommen diese Abschnitte vor dem Login)

routen: ['', 'über', 'Kontakt']

  1. App-angemeldete Seiten (Ich habe eine andere Kopf- und Fußzeile in diesem Abschnitt für alle App-Seiten, aber diese Kopf- und Fußzeile unterscheidet sich von der Kopf- und Fußzeile der Marketing-Site.)

routen: ['Dashboard', 'Profil']

Ich führe die App vorübergehend aus, indem ich meiner Routerkomponente html eine Kopf- und Fußzeile hinzufüge. 

Bitte beraten Sie mich zu einer besseren Vorgehensweise.

Das ist mein Code:

app\app.routing.ts

   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>

Ich habe diese Frage beim Stack-Overflow gesehen, aber aus dieser Antwort habe ich kein klares Bild erhalten 

39
ninja dev

Sie können Ihr Problem mithilfe von untergeordneten Routen lösen.

Siehe Arbeitsdemo unter https://angular-multi-layout-example.stackblitz.io/ oder editieren Sie unter https://stackblitz.com/edit/angular-multi-layout-example

Legen Sie Ihre Route wie folgt fest

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

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

78
Rameez Rami

sie können ein Kind verwenden, z.

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 und AdminComponent mögen

<app-header-main></app-header-main>
<router-outlet></router-outlet>
<app-footer-main></app-footer-main>

die Post spricht darüber, dass die Routen in verschiedenen Dateien getrennt sind

8
Eliseo

In einigen Fällen stimmen das Layout und die gemeinsam genutzten Elemente nicht wirklich mit der Routing-Struktur überein, oder einige Elemente müssen je nach Route ausgeblendet/angezeigt werden. In solchen Fällen kann ich mir die folgenden Strategien vorstellen (nehmen wir ein Beispiel für die Komponente app-header-main - sie gilt jedoch offensichtlich für alle gemeinsam genutzten Seitenelemente):

Eingaben & CSS-Klassen

Sie können Eingaben oder CSS-Klassen bereitstellen, um das innere Erscheinungsbild Ihrer freigegebenen Elemente zu steuern, z.

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

oder

  1. <app-header-main class="no-user-tools"></app-header-main> Und dann mit: Host (.no-user-tools) ein-/ausblenden, was sein muss

oder

  1. auf Routenebene (Kind oder nicht):

    {
      path: 'home',
      component: HomeComponent,
      data: {
        header: {showUserTools: true},
      },
    },
    

Und greifen Sie wie folgt über ActivatedRoute darauf zu: this.route.data.header.showUserTools

TemplateRef-Eingabe

Innerhalb der Komponente app-header-main:

@Input() rightSide: TemplateRef<any>;

Eingabe vom Typ TemplateRef<any>, Bei der Sie ein ng-template - Element direkt eingeben können

<app-header-main [rightSide]="rightside"></app-header-main>
<ng-template #rightside>your content here</ng-template>

Benannte Slot-Transklusion

Sie können den App-Header-Main so erstellen, dass er die Transklusion von benannten Slots verwendet

Innerhalb der App-Header-Hauptvorlage:

<ng-content select="[rightSide]"><ng-content>

Verwendungszweck:

<app-header-main class="no-user-tools">
  <div rightSide>your content here</div>
</app-header-main>
1
user776686

Sie können das Problem lösen, indem Sie ng-content + ViewChild verwenden und das Layout in jede Seitenkomponente einfügen, die dieses spezielle Layout verwendet.

Die Verwendung des Routers für diesen allgemeinen Anwendungsfall schien mir immer eine Problemumgehung zu sein. Was Sie möchten, ähnelt Layouts in Asp.Net MVC oder MasterPages in WebForm usw.

Nachdem ich damit zu kämpfen hatte, kam ich zu so etwas:

siehe Arbeitsdemo: 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 - ohne 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 - mit 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';
  }
}
0
Cesar