2021. 2. 28. 11:09ㆍWEB.DEV/Angular
이번 포스팅에서는 Angular Material Bottom Sheet을 이용해서 특정한 동작을 했을 때 하단에서 메뉴가 올라오는 하단 메뉴를 만들어보겠습니다.
먼저 버튼 모듈인 MatButtonModule과 하단 메뉴를 위한 MatBottomSheetModule 모듈을 추가해주도록 하겠습니다.
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {AppComponent} from './app.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {MatButtonModule} from '@angular/material/button';
import {MatBottomSheetModule} from '@angular/material/bottom-sheet'
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatButtonModule,
MatBottomSheetModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
먼저 컴포넌트 템플릿에 버튼을 추가해주도록 하겠습니다.
<button
mat-button
>
추가하기
</button>
그러면 아래와 같이 버튼이 보입니다.
이제 이 버튼을 클릭했을 때 BottomSheet이 열리도록 해보겠습니다. 그러기 전에 먼저 MatBottomSheet의 open 함수를 보게 되면 인수로 컴포넌트와 템플릿을 받도록 되어 있습니다.
먼저 템플릿을 이용해서 만드는 방법을 알아보도록 하겠습니다. 템플릿을 이용하는 방법은 <ng-template>를 이용합니다. 아래와 같이 ng-template을 만들어줍니다.
<ng-template #bottomSheetTemplate>
<nav>
<ul>
<li *ngFor="let snack of snackList">
<button mat-button>{{snack}}</button>
</li>
</ul>
</nav>
</ng-template>
그 다음에 컴포넌트에서 불러온 후 MatBottomSheet open 함수에 추가를 해주도록 하겠습니다.
...
import {MatBottomSheet} from '@angular/material/bottom-sheet';
@Component({
...
});
export class AppComponent implements OnInit {
@ViewChild('bottomSheetTemplate') bottomSheetTemplate: TemplateRef<any>;
snackList: string[] = [
'홈런볼',
'썬칩',
'콘칩',
'다이제'
];
constructor(
private bottomSheet: MatBottomSheet
) {
}
...
openBottomSheet(): void {
this.bottomSheet.open(bottomSheetTemplate);
}
}
그리고 아까 추가해놓은 button 클릭 시 openBottomSheet 함수를 호출하도록 해주겠습니다.
<button
mat-button
(click)="openBottomSheet()"
>
추가하기
</button>
그 다음 버튼을 클릭하면 아래와 같이 하단 메뉴가 보이는것을 볼수 있습니다.
추가로 버튼 아래에 추가된 과자 목록을 만들고 하단 메뉴를 클릭했을 때 추가가 되도록 해보겠습니다.
먼저 추가된 과자 목록을 보여주기 위한 배열을 만들어 주고 템플릿에 추가를 해주도록 하겠습니다.
// app.component.ts
...
@Component({
...
});
export class AppComponent implements OnInit {
...
addedSnackList: string[] = [];
...
}
...
<h3>추가된 과자들</h3>
<ul *ngIf="snackList.length > 0; else emptyList">
<li *ngFor="let snack of addedSnackList">
{{snack}}
</li>
</ul>
<ng-template #emptyList>
<span>추가된 과자가 없습니다.</span>
</ng-template>
그럼 이제 추가하기를 클릭했을 때 나오는 하단 메뉴에 있는 버튼을 클릭 했을 때 목록에 추가되도록 해보겠습니다.
...
export class AppComponent implements OnInit {
...
addSnack(snack): void {
this.addedSnackList.push(snack);
}
}
...
<ng-template #bottomSheetTemplate>
<nav>
<ul>
<li *ngFor="let snack of snackList">
<button
mat-button
(click)="addSnack(snack)"
>{{snack}}</button>
</li>
</ul>
</nav>
</ng-template>
위와 같이 한 후 하단 메뉴에서 과자를 클릭하면 목록에 과자가 하나씩 추가되는 것을 볼수 있습니다.
만약 여기서 과자가 추가될 때 마다 하단 메뉴가 닫히도록 하기 위해서는 아래와 같이 MatBottomSheet에 dismiss 함수를 호출해주면 됩니다. 그러면 과자를 클릭할 때 마다 하단 메뉴가 닫히는 것을 볼수 있습니다.
...
addSnack(snack: string): void {
this.addedSnackList.push(snack);
this.bottomSheet.dismiss();
}
}
이번에는 컴포넌트를 생성해서 추가를 해보도록 하겠습니다. 먼저 Angualr CLI를 이용해서 컴포넌트를 생성해주겠습니다.
$ ng g c bottom-sheet --skip-tests
그리고 bottom-sheet.component.html에 위 템플릿 부분에 있는 nav를 붙여 넣도록 하겠습니다.
<nav>
<ul>
<li *ngFor="let snack of snackList">
<button
mat-button
(click)="addSnack(snack)"
>{{snack}}</button>
</li>
</ul>
</nav>
그리고 snackList와 addSnack 함수를 bottom-sheet.component.ts에 추가를 해주도록 하겠습니다.
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-bottom-sheet',
templateUrl: './bottom-sheet.component.html',
styleUrls: ['./bottom-sheet.component.scss']
})
export class BottomSheetComponent implements OnInit {
snackList: string[] = [
'홈런볼',
'썬칩',
'콘칩',
'다이제'
];
constructor() {
}
ngOnInit(): void {
}
addSnack(snack: string): void {
}
}
그 다음 아까 만들어둔 openBottomSheet 안에 open 함수 안의 템플릿을 BottomSheetComponent로 변경을 해주도록 하겠습니다. 그리고 확인을 하면 기존 템플릿을 추가했을 때와 동일하게 보이는 것을 볼수 있습니다.
이제 템플릿에서 과자를 클릭했을 때 추가된 과자 목록에 과자가 추가되도록 해보겠습니다. 그런데 여기서 추가된 과자 목록은 AppComponent에 있고 과자 목록은 BottomSheetComponent에 있습니다. 이때 AppComponent로 클릭한 과자를 MatBottomSheetRef를 이용해서 넘겨주고 AppComponent에서 받도록 하겠습니다.
...
import {MatBottomSheetRef} from '@angular/material/bottom-sheet';
@Component({
...
})
export class BottomSheetComponent implements OnInit {
...
constructor(
private bottomSheetRef: MatBottomSheetRef<BottomSheetComponent>
) {
}
...
addSnack(snack: string): void {
this.bottomSheetRef.dismiss(snack);
}
}
...
export class AppComponent implements OnInit {
...
openBottomSheet(): void {
const ref = this.bottomSheet.open(BottomSheetComponent);
ref.afterDismissed().subscribe(res => {
this.addedSnackList.push(res);
});
}
}
위와 같이 한 후 과자를 클릭을 하면 아래와 같이 과자들이 추가되는 것을 볼수 있습니다.
추가로 MatBottomSheet 옵션 몇가지를 알아보도록 하겠습니다.
- autoFocus : bottom sheet이 보여질 때 제일 처음 있는 포커스 가능한 요소에 포커스 여부를 설정하는 옵션입니다. true를 하면 포커스가 되고 false를 하면 포커스가 되지 않습니다.
- backdropClass : bottom sheet이 보일 때 나타나는 overlay의 클래스를 변경하는 옵션입니다.
- closeOnNavigation : 페이지를 뒤로 / 앞으로 이동을 할 때 bottom sheet 닫힘을 정하는 옵션입니다. true를 하면 이동을 할 때 닫히고 false를 하면 닫히지 않습니다.
- data : open 인수에 추가한 컴포넌트에 데이터를 전달할 때 사용하는 옵션입니다.
- direction : bottom sheet 안의 정렬을 정하는 옵션입니다. ltr과 rtl이 있습니다. ltr은 왼쪽에서 오른쪽으로, rtl은 오른쪽에서 왼쪽으로 입니다(기본적으로 ltr이 설정되어 있습니다).
- disableClose : bottom sheet 밖을 클릭했을 때 닫힘 여부를 설정하는 옵션입니다. true를 하면 bottom sheet 밖을 클릭 했을 때 닫히지 않고 false를 하면 닫힙니다(기본적으로 false가 설정되어 있습니다).
- hasBackdrop : overlay를 보여줄건지 정하는 옵션입니다. true를 하면 보여지고 false를 하면 안 보입니다.
- panelClass : bottom sheet이 보여지는 패널의 클래스를 변결할 때 사용하는 옵션입니다.
여기에 나와있지 않는 옵션과 좀 더 자세한 설명은 Material BottomSheet API에서 확인하실수 있습니다.
부족한 글 읽어주셔서 감사합니다💛
'WEB.DEV > Angular' 카테고리의 다른 글
[Angular] Angular Material Badge를 이용한 알림 뱃지 만들기 (0) | 2021.02.27 |
---|---|
[Angular] Angular Material Autocomplete를 이용한 자동완성 만들기 (0) | 2021.02.27 |
[Angular] Material mat menu 유지하고 닫기 (0) | 2021.02.27 |
[Bitbucket] Bitbucket pipeline을 이용한 Firebase에 Angular 배포하기 (0) | 2021.02.08 |
[Angular] Angular CLI 뜯어 보기 (0) | 2021.02.05 |