Giao diện
Câu hỏi thường gặp — Collection Tree
Sử dụng chung
Collection Tree khác gì collection bình thường?
Collection Tree sử dụng AdjacencyListRepository thay vì Repository mặc định. Điều này bổ sung:
- Trường
parentIdđể tạo quan hệ cha-con - Bảng path phụ trợ (
{dataSource}_{collection}_path) để tối ưu truy vấn cây - Các action đặc biệt:
listChildren, truy vấn vớitree=true - Hiển thị dạng cây trên giao diện với lazy loading và drag & drop
- Trường
hasChildrentự động cho mỗi node
Có thể chuyển collection thường thành Tree collection không?
Không hỗ trợ chuyển đổi trực tiếp. Bạn cần tạo collection mới với tùy chọn Tree, sau đó migrate dữ liệu từ collection cũ sang. Đảm bảo dữ liệu có trường parentId hợp lệ trước khi import.
Xóa bản ghi cha thì các con có bị xóa không?
Không mặc định. Khi xóa bản ghi cha:
- Bản ghi cha bị xóa khỏi collection và bảng path
- Các bản ghi con vẫn tồn tại nhưng
parentIdcủa chúng trỏ đến bản ghi không còn tồn tại - Trên giao diện, các con này sẽ không hiển thị trong cây (vì parent không tìm thấy)
Khuyến nghị: Trước khi xóa node cha, hãy di chuyển các node con sang cha khác hoặc đặt parentId = null để chúng trở thành node gốc.
Lazy loading hoạt động như thế nào?
Khi tham số lazyLoad=true:
- Lần đầu chỉ tải các node gốc (
parentId = null) - Mỗi node gốc kèm cờ
hasChildren(dựa trênCOUNTchildren thực tế trong database) - Khi người dùng click mở rộng node, gọi action
listChildrenvớiparentId - Server trả về children trực tiếp kèm
hasChildrenvà__index
Điều này giúp giảm đáng kể lượng dữ liệu tải ban đầu cho cây lớn.
__index là gì và dùng để làm gì?
__index là chuỗi mô tả vị trí của node trong cây, ví dụ "2.children.1.children.0". Chuỗi này được tính bằng cách đếm số anh em (siblings) đứng trước node tại mỗi cấp. Nó được sử dụng cho:
- Drag & drop: Xác định vị trí gốc và đích khi kéo thả
- Rendering: Giúp UI biết chính xác vị trí để chèn/cập nhật node
Bảng path phụ trợ là gì?
Mỗi Tree Collection có một bảng path tự động, tên theo quy tắc {dataSourceName}_{collectionName}_path. Bảng này lưu:
nodePk: Primary key của nodepath: Đường dẫn đầy đủ, ví dụ/1/5/10(gốc là 1, cha là 5, node hiện tại là 10)rootPk: Primary key của node gốc (để nhóm nhanh theo cây)
Bảng path giúp:
- Tìm nhanh toàn bộ tổ tiên hoặc con cháu của một node
- Hỗ trợ filter: khi lọc dữ liệu, tìm path để build lại cây chỉ gồm nhánh liên quan
- Đếm root node chính xác khi có filter
Cấu hình
Có thể thay đổi tên trường parentId không?
Có. Trường liên kết cha được xác định qua treeParentField.foreignKey. Mặc định là parentId, nhưng bạn có thể cấu hình khác khi định nghĩa collection.
Collection Tree hỗ trợ những database nào?
Hỗ trợ tất cả database mà Digiforce hỗ trợ: PostgreSQL, MySQL, MariaDB, SQLite. Bảng path sử dụng các kiểu dữ liệu cơ bản (string, bigInt) nên tương thích mọi database.
Lỗi thường gặp
Cây không hiển thị đúng
Nguyên nhân có thể:
parentIdtrỏ đến bản ghi không tồn tại → node không xuất hiện trong cây- Dữ liệu bảng path bị lệch so với dữ liệu thực → chạy lệnh đồng bộ path
- Circular reference (A → B → A) → hệ thống chặn ở
beforeSavenhưng nếu dữ liệu cũ có thể bị
Cách xử lý:
- Kiểm tra dữ liệu
parentIdcó hợp lệ - Nếu nghi ngờ bảng path lệch, có thể dùng command
sync-pathđể đồng bộ lại
Lỗi "Cannot set itself as the parent node"
Nguyên nhân: Bạn đang cố đặt parentId bằng chính id của bản ghi.
Cách xử lý: Chọn một bản ghi cha khác hoặc đặt parentId = null để biến thành node gốc.
Lỗi "Collection X is not a tree collection"
Nguyên nhân: Gọi action listChildren trên collection không phải Tree collection.
Cách xử lý: Đảm bảo collection có option tree: 'adjacency-list'. Nếu chưa, cần tạo lại collection với tùy chọn Tree.
Di chuyển node rất chậm
Nguyên nhân: Khi thay đổi parentId, plugin cần cập nhật path của node và toàn bộ con cháu. Nếu nhánh cây có nhiều node (hàng trăm, hàng ngàn), thao tác này tốn thời gian.
Cách xử lý:
- Tránh di chuyển node gốc có cây con rất lớn
- Thực hiện trong giờ thấp điểm nếu cần
- Cân nhắc chia nhỏ cây nếu quá sâu/rộng