Vòng đời sự kiện Editor

Phạm vi áp dụng

✅ Bravo 8 · ✅ Bravo 10 ⚠️ Bravo 10 bổ sung 4 sự kiện quanh transaction

Đây là note quan trọng nhất để debug: khi một Evaluator “không chạy” hoặc “chạy sai lúc”, gần như luôn là do đặt sai sự kiện.

1. Luồng TẢI dữ liệu

flowchart TD
    A["Người dùng mở form / F3 / Ctrl+F2"] --> B["ServerLoading<br/>bổ sung cột vào câu SELECT"]
    B --> C["Query xuống CSDL"]
    C --> D["ServerLoaded<br/>chỉ chạy khi F3 hoặc Ctrl+F2"]
    D --> E["Khởi tạo Control"]
    E --> F["Eval có thẻ Controls ở bảng mẹ<br/>(ưu tiên chạy trước)"]

Bẫy kinh điển

Không đặt Evaluator điều khiển control (Visible, Enabled, Style…) trong ServerLoaded hoặc RowAdded của bảng con/cháu — lúc đó control chưa được khởi tạo nên Eval vô tác dụng.

→ Phải đặt ở bảng mẹ.

2. Luồng THÊM / NHÂN BẢN dòng

Thao tácSự kiện được gọi
F2 — thêm mới bảng mẹRowAdded
Ctrl+F2 — nhân bảnRowCopied + ServerLoaded
Thêm dòng ở GridRowAdded
Import dữ liệuRowImported → rồi mới tới RowAdded/RowCopied

Trình tự chi tiết khi thêm 1 dòng bằng giao diện:

  1. Thêm 1 dòng trắng — giá trị cột bằng NULL hoặc DefaultValues
  2. Thực hiện RowAdded
  3. Gán giá trị nếu có (zCarryingColumns, Copy/Paste dòng)
  4. Thực hiện ColumnChanging, ColumnChanged nếu bị ảnh hưởng bởi việc gán giá trị
  5. Không gọi TableSummed

Note

BravoAddRowEvaluator được coi như người dùng click thêm dòng mới → thực hiện tương tự.

3. Luồng THAY ĐỔI giá trị ô

flowchart LR
    A["Người dùng gõ giá trị"] --> B["ColumnChanging<br/>(chưa hoàn thành thay đổi)"]
    B --> C["Giá trị được ghi vào cột"]
    C --> D["ColumnChanged<br/>(đã thay đổi)"]
    D --> E["Các Evaluator được gọi"]
    E -.->|"có thể lồng nhau"| D

Kiểm soát việc gọi lồng nhau bằng allowRunning (Nonnested) và bSuppressChangeEvents.

4. Luồng LƯU dữ liệu

Bravo 8

flowchart TD
    A["Người dùng Lưu"] --> B["ServerUpdating<br/>(client) chuẩn bị dữ liệu"]
    B --> C["Validator kiểm tra"]
    C --> D["ServerCommand/Select, Merge"]
    D --> E["INSERT / UPDATE / DELETE"]
    E --> F["ServerUpdated<br/>sau khi lưu từng bảng"]
    F --> G["ServerCommand/BeforeCommit<br/>(backend, cùng transaction)"]
    G --> H["COMMIT"]
    H --> I["ServerCommand/AfterCommit<br/>(sau khi commit)"]

Bravo 10 — bổ sung 4 sự kiện

Sự kiệnChạy ở đâuThời điểm
BeforeTransactionClientDanh sách các evaluator được kích hoạt trước khi dữ liệu được gửi lên backend
BeforeCommitBackendDanh sách thủ tục kích hoạt sau khi dữ liệu đã cập nhật thành công nhưng trước khi commit transaction
AfterCommitBackendDanh sách thủ tục kích hoạt sau khi transaction được committed thành công
AfterTransactionClientDanh sách các evaluator kích hoạt sau khi quá trình cập nhật dữ liệu tại backend thành công

Bravo 10 giữ nguyên cơ chế cũ

Các sự kiện <ServerLoaded/>, <RowAdded/>, <RowCopied/>, <RowImported/>, <RowDeleting/>, <ColumnChanging/>, <ColumnChanged/> ở Bravo 10 giữ nguyên cơ chế như bản trước.

5. Luồng XÓA dòng

Sự kiệnKhi nào
RowDeletingBắt đầu xóa — giá trị các dòng vẫn còn, dùng để tính toán
TableSummedChạy 1 lần cuối cùng sau khi xóa xong (tên cũ: RowDeleted)

6. Bảng tổng hợp — thẻ nào được gọi khi nào

Thao tácRowAddedColumnChanging / ColumnChangedRowDeletingTableSummed
Thêm dòng bằng giao diệnGọi
(hỗ trợ bSuppressChangeEvents)
Gọi
(hỗ trợ bSuppressChangeEvents)
—Không gọi
Thêm dòng bằng BravoAddRowEvaluatorGọi
(hỗ trợ bSuppressChangeEvents)
Gọi
(hỗ trợ bSuppressChangeEvents)
—Không gọi
Thêm / xóa bằng BravoServerConstraintKhông gọi
(cố tình, để tăng tốc — thủ tục cần chuẩn bị hết dữ liệu)
Gọi
(hỗ trợ bSuppressChangeEvents)
—Luôn gọi 1 lần cuối cùng
Xóa dòng bằng giao diện—Không gọiLuôn gọi với từng dòngLuôn gọi 1 lần cuối cùng
Xóa dòng bằng BravoDeleteRowEvaluator—Không gọiLuôn gọi với từng dòngKhông gọi

Warning

Nếu dùng BravoDeleteRowEvaluator thì TableSummed không thực hiện → phải chủ động gọi Eval tính lại tổng.

Xem tiếp