สำหรับการใช้งานใน 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 มาใช้ในngAfterViewInitngOnChanges: เมื่อข้อมูลที่ส่งมาจาก@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 สร้างขึ้น เพื่อไม่ให้เกิดอาการหน่วงเมื่อใช้งานแอปพลิเคชันไปนาน ๆ
อ่านเพิ่มเติม