[Angular][Material] Sidenavでナビゲーションバーを設置
Angular Materialには、折りたたみ可能なサイドコンテンツ(多くの場合ナビゲーションですが、どんなコンテンツでも構いません)を主要コンテンツの横に追加するためのコンポーネントが2セットあります。これらはsidenavコンポーネントとdrawerコンポーネントです。
import {MatSidenavModule} from '@angular/material/sidenav';
要素
<mat-drawer-container>でナビゲーションを展開する領域を囲います。
ナビゲーション本体は<mat-drawer>で囲います。
<mat-drawer-container>
<mat-drawer>
同一コンポーネント内で開閉ボタンを設置
ナビゲーションと開閉ボタンを同一コンポーネントに設置する場合です。
html
mat-sidenav-module\mat-sidenav-module.component.html
<mat-drawer-container class="sidenavContainer" autosize>
<mat-drawer #drawer class="drawer" mode="side">
<p>ぽち</p>
<img
src="https://material.angular.io/assets/img/examples/shiba2.jpg"
alt="Photo of a Shiba Inu"
height="200px"
width="auto"
>
</mat-drawer>
<div class="content">
<p>ParentComponent!</p>
<button mat-raised-button color="primary" (click)="drawer.toggle()">Toggle Sidenav</button>
</div>
</mat-drawer-container>
component
mat-sidenav-module\mat-sidenav-module.component.ts
import { Component, OnInit} from '@angular/core';
@Component({
selector: 'app-mat-sidenav-module',
templateUrl: './mat-sidenav-module.component.html',
styleUrls: ['./mat-sidenav-module.component.css']
})
export class MatSidenavModuleComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
css
mat-sidenav-module\mat-sidenav-module.component.css
.sidenavContainer {
height: 100%;
border: 1px solid rgba(0, 0, 0, 0.5);
}
.drawer {
padding: 10px;
}
.content {
display: flex;
flex-direction: column;
height: 50%;
align-items: center;
}
開閉ボタンのイベントは上記のように直接htmlでdrawer.toggle()
のように指定してもOK。
コンポーネントから下記のようにクリックインベントで指定してもOK。
@ViewChild('drawer') drawer!: any;
onClick() {
this.drawer.toggle();
}
子コンポーネントから開閉ボタンを設置
親コンポーネントのナビゲーションを子コンポーネントから開閉する場合です。
親html
mat-sidenav-module\mat-sidenav-module.component.html
<mat-drawer-container class="sidenavContainer" autosize>
<mat-drawer #drawer class="drawer" mode="side">
<p>ぽち</p>
<img
src="https://material.angular.io/assets/img/examples/shiba2.jpg"
alt="Photo of a Shiba Inu"
height="200px"
width="auto"
>
</mat-drawer>
<div class="content">
<p>ParentComponent!</p>
<button mat-raised-button color="primary" (click)="drawer.toggle()">Toggle Sidenav</button>
</div>
**<app-sidenav-child [drawer]="drawer"></app-sidenav-child>**
</mat-drawer-container>
- 子コンポーネントに
drawer
を渡します。
親component
mat-sidenav-module\mat-sidenav-module.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
@Component({
selector: 'app-mat-sidenav-module',
templateUrl: './mat-sidenav-module.component.html',
styleUrls: ['./mat-sidenav-module.component.css']
})
export class MatSidenavModuleComponent implements OnInit {
@ViewChild('drawer') drawer!: MatSidenav;
constructor() { }
ngOnInit(): void {
}
}
- 子コンポーネントに渡すため、
viewChild
でテンプレートのdrawer要素を取得します
子html
mat-sidenav-module\sidenav-child\sidenav-child.component.html
<div class="childContent">
<p>ChildComponent!</p>
<button mat-stroked-button color="accent" (click)="onClick()">Toggle Sidenav</button>
</div>
子component
mat-sidenav-module\sidenav-child\sidenav-child.component.ts
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-sidenav-child',
templateUrl: './sidenav-child.component.html',
styleUrls: ['./sidenav-child.component.css']
})
export class SidenavChildComponent implements OnInit {
@Input()
drawer: any;
constructor() { }
ngOnInit(): void {
}
onClick() {
this.drawer.toggle();
}
}
-
Input()
で親コンポーネントからdrawerを受け取ります -
toggle()
メソッドで開閉します
css
mat-sidenav-module\sidenav-child\sidenav-child.component.css
.childContent {
display: flex;
flex-direction: column;
height: 50%;
align-items: center;
border: 1px solid rgba(0, 0, 0, 0.5);
}
メソッド
ナビゲーションを開く
open()
ナビゲーションを閉じる
close()
ナビゲーションの開閉トグル
toggle()
参考
Discussion