สำหรับการใช้งานใน Angular เราจะใช้ประโยชน์จาก Lifecycle Hooks และ @ViewChild เพื่อเข้าถึง DOM Element ครับ โดยแนวคิดจะเน้นไปที่การรักษา Instance ไว้ใน Property ของ Class เพื่อเรียกใช้งานซ้ำ ( Reused ) และทำลายทิ้งเมื่อ Component ถูกถอดออก (Unmount)
นี่คือตัวอย่างการปรับใช้ TabulatorPlus ใน Angular ครับ
user-table.component.ts
import { Component, ElementRef, Input, OnChanges, OnDestroy, AfterViewInit, ViewChild, SimpleChanges } from '@angular/core';
import TabulatorPlus from './TabulatorPlus';
@Component({
selector: 'app-user-table',
template: `
<div class="table-controls">
<button (click)="refreshTable()">Redraw Table</button>
<button (click)="clearFilters()">Clear Filters</button>
</div>
<div #tableElement></div>
`,
styles: [`
.table-controls { margin-bottom: 10px; }
:host ::ng-deep .tabulator { border: 1px solid #ccc; } /* จัดการ CSS Scoping */
`]
})
export class UserTableComponent implements AfterViewInit, OnChanges, OnDestroy {
// 1. อ้างอิงถึง HTML Element ใน Template
@ViewChild('tableElement', { static: true }) tableElement!: ElementRef;
// 2. รับข้อมูลจาก Parent Component
@Input() data: any[] = [];
// 3. เก็บ Instance ไว้เพื่อใช้งานซ้ำ (Reused Instance)
private tabulatorInstance: any;
constructor() {}
// 4. Initialize: สร้างตารางเมื่อ View พร้อมใช้งาน
ngAfterViewInit(): void {
this.tabulatorInstance = new TabulatorPlus(this.tableElement.nativeElement, {
data: this.data,
columns: [
{ title: "Name", field: "name", width: 150 },
{ title: "Role", field: "role" },
{ title: "Last Login", field: "lastLogin" },
],
}, "angular-storage-key");
}
// 5. Refresh: อัปเดตข้อมูลเมื่อ Props (Input) เปลี่ยนแปลง
ngOnChanges(changes: SimpleChanges): void {
if (changes['data'] && this.tabulatorInstance) {
console.log("Refreshing data...");
// ใช้ .setData() เพื่ออัปเดตข้อมูลโดยไม่ต้องสร้างตารางใหม่
this.tabulatorInstance.setData(this.data);
}
}
// 6. Manual Actions: การเรียกใช้ Instance จากฟังก์ชันอื่น
refreshTable(): void {
if (this.tabulatorInstance) {
this.tabulatorInstance.redraw(true);
}
}
clearFilters(): void {
if (this.tabulatorInstance) {
this.tabulatorInstance.clearFilter(true);
}
}
// 7. Unmount & Cleanup: ล้างข้อมูลและทำลาย Instance
ngOnDestroy(): void {
if (this.tabulatorInstance) {
console.log("Cleaning up Tabulator before component destroy...");
this.tabulatorInstance.destroy(); // ป้องกัน Memory Leak
this.tabulatorInstance = null;
}
}
}
💡 จุดที่ควรทราบสำหรับ Angular
@ViewChildและElementRef: ใน Angular เราไม่ควรใช้document.getElementByIdแต่ควรใช้@ViewChildเพื่อดึง reference ของ element มาใช้ในngAfterViewInit( จุดที่ DOM พร้อมที่สุด )ngOnChanges: เมื่อข้อมูลที่ส่งมาจาก@Input() dataเปลี่ยนแปลง Hook นี้จะทำงาน เราจึงใช้.setData()ตรงนี้เพื่อทำ Hot Refresh ข้อมูลในตารางโดยที่ User ไม่รู้สึกว่าตารางถูกโหลดใหม่::ng-deep: Angular มีระบบ View Encapsulation ( การแยก CSS ของแต่ละ Component ) หากคุณต้องการเขียน CSS ทับ Style ของ Tabulator ภายในไฟล์.scssของ Component ต้องใช้คำสั่ง::ng-deepเพื่อให้ Style เข้าถึง Library ภายนอกได้ngOnDestroy( Unmount ): สำคัญมากสำหรับการล้าง Event Listeners และ DOM ที่ Tabulator สร้างขึ้น เพื่อไม่ให้เกิดอาการหน่วงเมื่อใช้งานแอปพลิเคชันไปนาน ๆ
อ่านเพิ่มเติม
