Xử lý Các Vấn Đề Khi Sử Dụng kbmMWSmartBind Với ListView

Kiểm soát thời điểm thực hiện việc ràng buộc là vấn đề đầu tiên cần chú ý. Trong ví dụ trước đây, chúng ta sử dụng MemTable nên không gặp khó khăn này. Tuy nhiên, khi sử dụng TClientQuery để thực hiện truy vấn và nhận dữ liệu, việc mở lại ClientQuery sau mỗi lần truy vấn sẽ làm cho các đối tượng TField bị xóa và tạo lại, gây ra lỗi nếu không xử lý đúng cách. Dưới đây là đoạn mã đã được kiểm tra:

    FBindOrder.UpdateEvent.Deactivate; // Tạm dừng cập nhật ràng buộc
    FBindOrder.Reset; // Xóa các ràng buộc hiện tại
    Scheduler.Schedule(
      procedure(const Event: IkbmMWScheduledEvent)
      begin
         ...
         ClientQuery.Execute; // Thực hiện truy vấn
      end).ThenExecute(
      procedure(const Event: IkbmMWScheduledEvent)
      begin
       FBindOrder.Bind(ClientQuery, 'MaDonHang', ListView, '#ma_don_hang').SetDestinationExpression('"Số đơn hàng:" + data');
       ...
        FBindOrder.UpdateEvent.Activate; // Bật lại cập nhật ràng buộc
      end).OnException(
      procedure(const Ex: Exception)
      begin
        HiểnThịLỗi(Ex);
      end).Start;

Mã trên đảm bảo rằng SmartBind hoạt động bình thường khi thực hiện nhiều lần. Như vậy, trước khi mở ClientQuery, hãy xóa các ràng buộc cũ và thực hiện ràng buộc lại sau khi mở ClientQuery. Lý do là phương thức Bind thêm các trường dữ liệu và các đối tượng giao diện vào danh sách nội bộ của FBindOrder và cập nhật dựa trên danh sách này. Khi ClientQuery được đóng và mở lại, các trường dữ liệu sẽ được tạo lại và không còn là những đối tượng cũ, do đó cần phải ràng buộc lại.

Vấn đề thứ hai liên quan đến việc thực hiện ràng buộc một cách bất đồng bộ. Mặc định, SmartBind sử dụng một bộ lập lịch để đồng bộ hóa nguồn dữ liệu với mục tiêu mỗi 100 millisecond, điều này có nghĩa là nó hoạt động bất đồng bộ. Dưới đây là đoạn mã minh họa vấn đề này:

var
FBindSanPham: TkbmMWBindings;
begin
   ...  
   FBindSanPham := TkbmMWBindings.Create;
   FBindSanPham.Reset;
   ClientQuerySanPham.Execute;
   FBindSanPham.Bind(ClientQuerySanPham, 'TenSanPham', EditBox, 'Text');
   ...
   EditBox.Text:='BMW X6';
   ShowMessage(ClientQuerySanPham.FieldByName('TenSanPham').AsString);
   ...

Trong đoạn mã trên, chúng ta đã ràng buộc một trường dữ liệu với thuộc tính Text của EditBox, sau đó thay đổi giá trị của EditBox và hiển thị giá trị của trường dữ liệu thông qua ShowMessage. Kết quả là ShowMessage không hiển thị "BMW X6". Điều này xảy ra vì SmartBind chưa kịp cập nhật giá trị từ EditBox vào trường dữ liệu. Vì vậy, khi thay đổi nguồn hoặc mục tiêu, chúng ta không thể lấy giá trị mới ngay lập tức do sự bất đồng bộ.

Cuối cùng, việc giải phóng các đối tượng ràng buộc cũng rất quan trọng. SmartBind cung cấp một đối tượng ràng buộc toàn cục Binding, nhưng trong thực tế, chúng ta cần tự tạo và giải phóng các đối tượng kbmMWBindings. Dưới đây là cách giải phóng đối tượng FBindSanPham được sử dụng trong ví dụ thứ hai:

procedure TMyFrame.TrướcKhiHủy;
begin
  bnd:=nil;
  FBindSanPham.Tắt;
  FBindSanPham.GiảiPhóng;

  KếThừa;
end;

Bằng cách giải phóng như trên, ứng dụng sẽ hoạt động ổn định bất kể khi nào tắt, ngược lại sẽ gây ra nhiều lỗi liên quan đến bộ nhớ.

Thẻ: kbmMWSmartBind ListView TClientQuery RàngBuộcDữLiệu

Đăng vào ngày 12 tháng 6 lúc 22:25