私はangularが初めてです。達成しようとしているのは、アプリのさまざまなページにさまざまなレイアウトヘッダーとフッターを設定することです。私は3つの異なるケースがあります:
ルート:['login'、 'register']
ルート:[''、 'about'、 'contact']
ルート:['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);
<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>
スタックオーバーフローで この質問 を見ましたが、その答えから明確な画像が得られませんでした
子ルートを使用して問題を解決できます。
https://angular-multi-layout-example.stackblitz.io/ の作業デモを参照するか、 https://stackblitz.com/edit/angular-multi-layout-で編集します例
以下のようにルートを設定します
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);
子を使用できます。
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とAdminComponentのような
<app-header-main></app-header-main>
<router-outlet></router-outlet>
<app-footer-main></app-footer-main>
異なるファイル内のルートについての個別の話
レイアウトと共有要素が実際にルーティング構造と一致しない場合や、ルートごとにいくつかの要素を非表示/表示する必要がある場合があります。そのような場合、次の戦略を考えることができます(app-header-main
コンポーネントの例を見てみましょう-しかし、それは明らかに共有ページ要素に適用されます):
入力またはcssクラスを提供して、次のような共有要素の内部外観を制御できます。
<app-header-main [showUserTools]="false"></app-header-main>
または
<app-header-main class="no-user-tools"></app-header-main>
してから:Host(.no-user-tools)を使用して、必要なものを表示/非表示しますまたは
ルートレベル(子かどうか):
{
path: 'home',
component: HomeComponent,
data: {
header: {showUserTools: true},
},
},
そして、ActivatedRoute
からアクセスします:this.route.data.header.showUserTools
内部app-header-main
コンポーネント:
@Input() rightSide: TemplateRef<any>;
TemplateRef<any>
要素を直接フィードできるタイプng-template
の入力
<app-header-main [rightSide]="rightside"></app-header-main>
<ng-template #rightside>your content here</ng-template>
名前付きスロットトランスクルージョンを使用するようにapp-header-mainを作成できます
App-header-mainテンプレートの内部:
<ng-content select="[rightSide]"><ng-content>
使用法:
<app-header-main class="no-user-tools">
<div rightSide>your content here</div>
</app-header-main>
Ng-content + ViewChildを使用して、特定のレイアウトを使用する各ページコンポーネントにレイアウトを挿入することで問題を解決できます。
この一般的なユースケースにルーターを使用することは、常に回避策のように思えました。必要なものは、Asp.Net MVCのレイアウトやWebFormなどのMasterPagesに似ています。
これに苦労した後、私はこのようなものになりました:
作業デモを参照してください: 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-ヘッダーなし
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-ヘッダー付き
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';
}
}