ก่อนหน้านี้ ผมได้ลองใช้งาน dialog แบบต่างๆ มาพอสมควร เช่น Bootstrap Modal หรือแม้แต่สร้าง CSS ขึ้นมาใช้เอง จนเมื่อไม่นานมานี้ ได้ตัดสินใจ Material Dialog พบว่ามันใช้งานง่าย มีความยืดหยุ่น นำมาใช้ในโปรเจคได้เร็ว เอาละครับ มาเริ่มกันเลย
source: https://github.com/kdbeer/mat-dialog-example
หลังจากที่เราสร้างโปรเจคขึ้นมาแล้ว ก็ให้เราติดตั้ง Angular Material ด้วยคำสั่งด้านล่างนี้
npm install --save @angular/material @angular/cdk @angular/animations
หลังจากทำการติดตั้งเสร็จเรียบร้อยแล้ว ต่อไปให้เรานำไฟล์ CSS ไปวางไว้ที่ styles.scss เพื่อให้เราสามารถใช้ style ของ lib ได้
@import ‘~@angular/material/prebuilt-themes/deeppurple-amber.css’;
จากนั้นให้เราไปที่ module ที่เราต้องการใช้งาน แล้วให้เรา Import lib เข้ามาใช้งาน แนะนำว่าให้ import ใส่ module ที่ต้องใช้ก็พอ เพราะเวลาใช้งานจริงๆ เราควรจะทำ Lazy Load ซึ่งเราแยก Module ออกเป็นย่อยๆ อยู่แล้ว
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatDialogModule, MatNativeDateModule } from '@angular/material';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
MatDialogModule,
MatNativeDateModule,
BrowserAnimationsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
เอาละครับ หลังจาก Set Up เสร็จแล้ว ผมขออธิบายการทำงานของ Mat Dialog นิดนึง การใช้งาน Mat Dialog เราต้องสร้าง Component ที่เราจะใช้ทำ Dialog ขึ้นมาก่อน และนำ component ที่เราเพิ่งสร้างขึ้นมา ไป Declare ไว้ใน entryComponents ของ Module เมื่อเราสั่งให้เปิด Dialog ก็จะเป็นการเปิด Component นั้นใน Container ของ Mat Dialog ซึ่งข้อดีหลักๆ เลย คือ มันมี LifeCycle ของ Component นั้นๆ ชัดเจน
มาต่อการเลยครับให้เราสร้าง Folder ชื่อ components ขึ้นมาใน module ที่เราต้องการ แล้วให้เราสร้าง component เพื่อใช้สร้าง dialog ขึ้นมา
ng g c simple-dialog --spec false
และให้เรานำ component ที่เราเพิ่งสร้างนี้ไป Declare ไว้ใน entryComponents ที่ module ของเรา
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
MatDialogModule,
MatNativeDateModule,
BrowserAnimationsModule
],
providers: [],
bootstrap: [AppComponent],
entryComponents: [SimpleDialogComponent]
})
ทีนี้ เราก็มาเริ่มใช้งานกันเลย ให้เราไปที Component ที่เราต้องการใช้งาน จากให้ให้เรา Inject Service MatDialog ไว้ใน Constructor
app.component.ts
import { Component } from '@angular/core';
import { MatDialog } from '@angular/material';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'mat-dialog-example';
constructor(private dialog: MatDialog) {}
openSimpleDialog() {
this.dialog.open(SimpleDialogComponent, {
width: '950px'
});
}
}
ที่ Template ผมจะสร้างปุ่มไว้เปิด Dialog เป้าหมายของเรา
app.component.html
<button (click)="openSimpleDialog()">Simple Dialog</button>
ผลลัพธ์
แต่ทีนี้ถ้าเราอยากจะใส่ Data ลงไปด้วยละ ทำยังไง ง่ายมากครับ ถ้าสังเกตจากตัวอย่าง ผมสามารถใส่ parameter ที่ชื่อ width เป็น parameter ตอนเรียก Service ในขณะเดียวกัน ผมสามารถจะใส้ parameter ที่ชื่อ data ได้ด้วย โดยผมจะแก้ Method openSimpleDialog() ดังนี้ครับ
openSimpleDialog() {
this.dialog.open(SimpleDialogComponent, {
width: '950px',
data: { author: 'KDBEER' }
});
}
ทีนี้ เราต้องไปแก้ไข Constructor ใน SimpleDialog โดยการทำให้มันสามารถ Inject Data เข้าไปได้ ซึ่งก็ง่ายมากๆ ครับ
simple-dialog.component.ts
constructor(@Inject(MAT_DIALOG_DATA) public data: any) {}
และแก้ไฟล์ Template เพื่อนำข้อมูลไปใช้ดังนี้
<p>
simple-dialog works!
</p>
<p>Author: {{ data['author'] }}</p>
ผลลัพธ์
เสร็จแล้วครับ จะเห็นได้ว่าการใช้งานไม่ได้ยุ่งยากอะไรเลย และถ้ามองดีๆ มันมีความยืดหยุ่นมาก เพราะ dialog นี้ มันประพฤติตัวเป็น Component 100% อารมณ์เหมือนกับเรากำลัง Route ไปหน้าใหม่นั่นละครับ
ถ้ามีข้อผิดพลาดหรือขอเสนอแนะประการใด ก็อย่ากังวลที่จะ Comment นะครับ แล้วเจอกันใหม่ครับ