Angular: TabulatorPlusAngular: TabulatorPlus

สำหรับการใช้งานใน Angular เราจะใช้ประโยชน์จาก Lifecycle Hooks และ @ViewChild เพื่อเข้าถึง DOM Element ครับ โดยแนวคิดจะเน้นไปที่การรักษา Instance ไว้ใน Property ของ Class เพื่อเรียกใช้งานซ้ำ และทำลายทิ้งเมื่อ 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
  • ngOnChanges: เมื่อข้อมูลที่ส่งมาจาก @Input () data เปลี่ยนแปลง Hook นี้จะทำงาน เราจึงใช้ .setData () ตรงนี้เพื่อทำ Hot Refresh ข้อมูลในตารางโดยที่ User ไม่รู้สึกว่าตารางถูกโหลดใหม่
  • ::ng-deep: Angular มีระบบ View Encapsulation หากคุณต้องการเขียน CSS ทับ Style ของ Tabulator ภายในไฟล์ .scss ของ Component ต้องใช้คำสั่ง ::ng-deep เพื่อให้ Style เข้าถึง Library ภายนอกได้
  • ngOnDestroy : สำคัญมากสำหรับการล้าง Event Listeners และ DOM ที่ Tabulator สร้างขึ้น เพื่อไม่ให้เกิดอาการหน่วงเมื่อใช้งานแอปพลิเคชันไปนาน ๆ

อ่านเพิ่มเติม