💻

Angularのビューで全ページ共通のヘッダー部分の内容を一部のページでだけ改変する

2018/06/23に公開

やりたかったこと

タイトルがやや分かりづらいですが、

こういう全ページ共通のヘッダー部分がある場合に、

こんな風に、一部のページでだけ(この場合はトップページ)そのヘッダー部分を改変したかった、ということです。

やったこと

大まかな流れは以下のとおりです。

  • ルートコンポーネントからヘッダーコンポーネントに「改変するかどうかのフラグ」を渡す
  • ヘッダーコンポーネントは、親から渡されたフラグに応じて内容を改変する
  • ルートコンポーネントは、 ページがアクティベートされる度に「改変フラグ」をセットし直す( router-outletactivate イベントバインディングを使う)

コード的には以下のようになります。

ヘッダーコンポーネント

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

@Component({
  selector: 'my-header',
  template: `
    <nav>MyApp</nav>
    <div *ngIf="needsDescription">Some description here</div> <!-- この div は needsDescription が true のときしか出力しない-->
  `,
})
export class HeaderComponent {
  @Input() needsDescription: boolean; // needsDescription はルートコンポーネントからもらう
}

ルートコンポーネント

import { Component } from '@angular/core';
import { WelcomeComponent } from './welcome.component';

@Component({
  selector: 'my-app',
  template: `
    <my-header [needsDescription]="isWelcomePage"></my-header> <!-- isWelcomePage の値を needsDescription プロパティにバインド -->
    <router-outlet (activate)="onActivate($event)"></router-outlet> <!-- activate イベントに onActivate メソッドをバインド -->
  `,
})
export class AppComponent {
  isWelcomePage: boolean = false;

  // activate イベントにバインドしてあるので、ルートがアクティベートされる度に実行される
  onActivate(e) {
    // アクティベートされたコンポーネントが WelcomeComponent だった場合のみ isWelcomePage が true になる(これがヘッダーコンポーネントに渡る)
    this.isWelcomePage = e instanceof WelcomeComponent;
  }
}

ルーティング設定

const routes = [
  { path: '', component: WelcomeComponent, pathMatch: 'full' },
  { path: 'page1', component: Page1Component },
  { path: 'page2', component: Page2Component },
];

これで、

  • URL / では <div>Some description here</div> が表示される
  • URL /page1/page2 では <div>Some description here</div> が表示されない

という動作が実現できます。

サンプル

動作サンプル置いときます。

https://stackblitz.com/edit/angular-modify-shared-header-for-some-specific-pages

GitHubで編集を提案

Discussion