Bỏ qua, đến nội dung

Cài đặt và sử dụng — Collection Tree

Tổng quan

Plugin Collection Tree bổ sung khả năng tổ chức dữ liệu theo cấu trúc phân cấp cha-con (tree/hierarchy) cho collection, sử dụng mô hình adjacency list (parentId). Ngoài ra, plugin tự động duy trì một bảng path phụ trợ để hỗ trợ truy vấn cây nhanh hơn.

Mô hình dữ liệu

Plugin sử dụng kết hợp hai mô hình:

Mô hìnhMô tảBảng
Adjacency listMỗi bản ghi có trường parentId trỏ đến bản ghi chaBảng collection chính
Path enumerationLưu đường dẫn đầy đủ từ gốc đến node, ví dụ /1/5/10Bảng {dataSource}_{collection}_path

Bảng path được tự động tạo và cập nhật khi thêm, sửa, xóa bản ghi.

Yêu cầu

  • Plugin đã được kích hoạt trong Plugin Manager
  • Collection cần được tạo với option tree: 'adjacency-list' hoặc bật Tree collection khi tạo trên giao diện

Bước 1: Kích hoạt Plugin

  1. Vào Settings → Plugin Manager
  2. Tìm plugin-collection-tree
  3. Bật toggle để kích hoạt

Bước 2: Tạo Collection dạng cây

  1. Vào Collection Manager → Add new
  2. Bật tùy chọn Tree collection
  3. Hệ thống tự động thêm trường parentId (foreign key) và tạo bảng path phụ trợ

Khi collection được tạo, plugin sẽ:

  • Đăng ký TreeCollection thay vì Collection thông thường
  • Sử dụng AdjacencyListRepository thay vì Repository mặc định
  • Tạo bảng path {dataSource}_{collection}_path với cấu trúc:
TrườngKiểuMô tả
nodePkbigInt (hoặc kiểu PK của collection)Primary key của node
pathstring(1024)Đường dẫn từ gốc, ví dụ /1/5/10
rootPkbigIntPrimary key của node gốc

Bước 3: Sử dụng trên giao diện

Hiển thị dạng cây

Khi truy vấn với tham số tree=true, hệ thống trả về dữ liệu dạng cây lồng nhau (nested). Node gốc (root) là những bản ghi có parentId = null.

Lazy loading

Plugin hỗ trợ lazy loading — chỉ tải node con khi người dùng mở rộng (expand) một node:

Mỗi node trả về kèm:

  • hasChildren: true/false — cho UI biết node có thể mở rộng tiếp
  • __index: Vị trí trong cây, ví dụ "2.children.1.children.0" — dùng cho drag & drop

Lọc dữ liệu

Khi có filter, plugin thực hiện:

  1. Tìm các node thỏa điều kiện filter
  2. Tra cứu bảng path để tìm toàn bộ đường dẫn từ gốc đến node
  3. Build lại cây chỉ gồm các nhánh chứa node thỏa filter

Các action được hỗ trợ

ActionMô tả
find (tree=true)Lấy dữ liệu dạng cây, hỗ trợ filter và phân trang
count (tree=true)Đếm số root node (khi có filter thì đếm root của các node thỏa filter)
findAndCountKết hợp find + count trong một transaction
listChildrenLazy load: lấy children trực tiếp của một node

Cơ chế tự động cập nhật path

Plugin đăng ký event listener cho collection cây để tự động duy trì bảng path:

EventHành động
afterCreateTính path từ gốc đến node mới, lưu vào bảng path
afterBulkCreateTương tự afterCreate nhưng cho nhiều bản ghi
afterUpdateNếu parentId thay đổi → cập nhật path của node và toàn bộ con cháu
afterBulkUpdateTương tự afterUpdate cho batch update
afterDestroyXóa path tương ứng khỏi bảng path
beforeSaveKiểm tra circular reference (node không được trỏ parentId về chính nó)

Lưu ý

Plugin tự động ngăn chặn circular reference — nếu bạn cố đặt parentId bằng chính id của bản ghi, hệ thống sẽ báo lỗi Cannot set itself as the parent node.

Ví dụ sử dụng thực tế

Danh mục sản phẩm nhiều cấp

Tất cả sản phẩm (root)
├── Điện tử
│   ├── Điện thoại
│   │   ├── iPhone
│   │   └── Samsung
│   └── Laptop
│       ├── MacBook
│       └── ThinkPad
└── Thời trang
    ├── Áo
    └── Quần

Cơ cấu tổ chức

Công ty ABC (root)
├── Ban Giám đốc
├── Phòng Kỹ thuật
│   ├── Team Backend
│   └── Team Frontend
└── Phòng Kinh doanh
    ├── Team Bắc
    └── Team Nam

Lưu ý về hiệu năng

  • Lazy loading được khuyến nghị cho cây có nhiều node (> 100)
  • Bảng path có index trên cột path (length 191) để tăng tốc truy vấn
  • Khi di chuyển node (thay đổi parentId), toàn bộ path con cháu cần được cập nhật — thao tác này có thể chậm nếu cây rất sâu
  • Không giới hạn số cấp, nhưng khuyến nghị giữ dưới 10 cấp để đảm bảo trải nghiệm người dùng