mydomain
No ADS
No ADS

FlutterArtist Internal Shelf Event ex1

  1. Cấu trúc của ví dụ
  2. SalesOrder96aShelf
  3. Create SalesOrderLine
  4. Edit SalesOrderLine
  5. Create SalesOrder
Trong FlutterArtist, các Block(s)Scalar(s) cùng Shelf sẽ phản hồi ngay lập tức (truy vấn lại hoặc làm mới ITEM) khi có sự kiện nội bộ phát sinh. Các tình huống kích hoạt bao gồm:
  • Tạo mới hoặc sửa đổi một ITEM thông qua Form.
  • Xoá một hoặc nhiều ITEM(s) trên một Block.
  • Thực thi các Action của Block, chẳng hạn BlockQuickItemCreationAction, BlockQuickItemUpdateAction hoặc BlockQuickMultiItemCreationAction.
  • Thưc thi các BlockBackendAction(s).
  • Thực thi các ScalarBackendAction(s).
Trong bài viết này, chúng ta sẽ xem xét ví dụ về việc tạo hoặc chỉnh sửa một SalesOrder cùng các SalesOrderLine(s) đi kèm.
Khi người dùng thêm mới, chỉnh sửa hoặc xóa một SalesOrderLine, hệ thống sẽ tự động làm mới SalesOrder. Cơ chế này đảm bảo tổng tiền trên đơn hàng luôn được cập nhật chính xác và hiển thị tức thì tới người dùng.
Chú ý: Ví dụ này khá phức tạp, mã nguồn đầy đủ của nó sẵn trong bản FlutterArtist Demo miễn phí dưới đây.
  • Download FlutterArtist Demo

1. Cấu trúc của ví dụ

Trên màn hình chính, phía bên trái là danh sách các SalesOrder(s), và bên phải hiển thị một SalesOrder hiện thời và danh sách các SalesOrderLine(s).
Khi người dùng nhấn nút tạo mới một SalesOrderLine một Dialog sẽ hiển thị cho phép bạn nhập thông tin vào một Form.

2. SalesOrder96aShelf

Trước hết hãy nhìn vào định nghĩa của Shelf sau đó chúng ta sẽ phân tích chi tiết nó.
SalesOrder96aShelf
class SalesOrder96aShelf extends Shelf {
  @override
  ShelfStructure defineShelfStructure() {
    return ShelfStructure(
      description: null,
      filterModels: {},
      blocks: [
        SalesOrder96aBlock(
          name: SalesOrder96aBlock.blkName,
          description: null,
          config: BlockConfig(
            pageable: Pageable(pageSize: 3),
            onInternalShelfEvents: InternalShelfEventBlockRecipient(
              itemLevelReactionOn: [
                Evt.ofBlock(SalesOrderLine96aBlock.blkName),
              ],
            ),
          ),
          filterModelName: null,
          formModel: SalesOrder96aFormModel(),
          childBlocks: [
            SalesOrderLine96aBlock(
              name: SalesOrderLine96aBlock.blkName,
              description: null,
              config: BlockConfig(),
              filterModelName: null,
              formModel: SalesOrderLine96aFormModel(),
              childBlocks: [],
            ),
          ],
        ),
      ],
    );
  }

  SalesOrder96aBlock findSalesOrder96aBlock() {
    return findBlock(SalesOrder96aBlock.blkName) as SalesOrder96aBlock;
  }

  SalesOrderLine96aBlock findSalesOrderLine96aBlock() {
    return findBlock(SalesOrderLine96aBlock.blkName) as SalesOrderLine96aBlock;
  }
}
SalesOrderLine96aBlock Config
Nhìn vào cấu hình của SalesOrderLine96aBlock thấy rằng nó bao gồm một FormModel, điều này có nghĩa là nó hỗ trợ việc thêm mới hoặc sửa đổi các ITEM(s) của nó thông qua Form và nó sẽ phát ra các sự kiện.
SalesOrderLine96aBlock Config
SalesOrderLine96aBlock(
  name: SalesOrderLine96aBlock.blkName,
  description: null,
  config: BlockConfig(),
  filterModelName: null,
  formModel: SalesOrderLine96aFormModel(),
  childBlocks: [],
),
No ADS
SalesOrder96aBlock Config
Cấu hình của SalesOrder96aBlock chỉ rõ rằng nó sẽ phản ứng với các sự kiện nội bộ.
  • itemLevelReactionOn: Định nghĩa các nguồn phát sự kiện sẽ làm Block này phản ứng ở mức ITEM, hay nói cách khác ITEM hiện tại của Block này sẽ được làm mới.
SalesOrder96aBlock Config
SalesOrder96aBlock(
  name: SalesOrder96aBlock.blkName,
  description: null,
  config: BlockConfig(
    pageable: Pageable(pageSize: 3),
    onInternalShelfEvents: InternalShelfEventBlockRecipient(
      itemLevelReactionOn: [
        Evt.ofBlock(SalesOrderLine96aBlock.blkName),
      ],
    ),
  ),
  ...
),
Hình dưới đây mô tả sự khác biệt giữa hai luồng vận hành: trường hợp SalesOrder96aBlock không lắng nghe và trường hợp có lắng nghe các sự kiện nội bộ Shelf phát ra từ SalesOrderLine96aBlock.

3. Create SalesOrderLine

Khi người dùng nhấn vào nút tạo mới trên BlockControlBar của SalesOrderLine96aBlock, hàm callback onNavigateCreate() sẽ được kích hoạt. Tại đây, bạn cần thực hiện logic để mở SalesOrderLine96aBlockDialog.
BlockControlBar (salesOrderLineBlock)
BlockControlBar(
  description: null,
  ownerClassInstance: this,
  block: salesOrderLineBlock,
  config: BlockControlBarConfig( 
    allowCreateButton: true, 
    onNavigateCreate: (PrepareItemCreationResult result) {
      _onNavigateCreateSalesOrderLine(context, result);
    },
    ...
  ),
),
No ADS
_onNavigateCreateSalesOrderLine()
void _onNavigateCreateSalesOrderLine(
  BuildContext context,
  PrepareItemCreationResult result,
) {
  FlutterArtist.codeFlowLogger.addMethodCall(
    ownerClassInstance: this,
    currentStackTrace: StackTrace.current,
    parameters: null,
  );
  if (result.successForFirst) {
    SalesOrderLine96aDialog.openDialog(context);
  }
}

4. Edit SalesOrderLine

Khi người dùng nhấn vào nút "Edit" để sửa đổi một SalesOrderLine bạn cần gọi thiết lập nó làm ITEM hiện thời và đảm bảo rằng dữ liệu liên quan của Form được tải thành công trước khi mở SalesOrderLine96aDialog.
_editSalesOrderLineDetail()
Future<void> _editSalesOrderLineDetail(
  BuildContext context,
  SalesOrderLineInfo salesOrderLine,
) async {
  // SalesOrderLine96aBlock block:
  BlockCurrentItemSettingResult result = await block
      .refreshItemAndSetAsCurrent(item: salesOrderLine, forceLoadForm: true);
  if (!result.successForAll) {
    return;
  }
  SalesOrderLine96aDialog.openDialog(context);
}

5. Create SalesOrder

Khi người dùng nhấn vào nút tạo mới trên BlockControlBar của SalesOrder96aBlock, hàm callback onNavigateCreate() sẽ được kích hoạt. Tại đây, bạn cần thực hiện logic để mở SalesOrder96aBlockDialog.
BlockControlBar (salesOrderBlock)
BlockControlBar(
  description: null,
  ownerClassInstance: this,
  block: salesOrderBlock,
  config: BlockControlBarConfig( 
    allowCreateButton: true, 
    onNavigateCreate: (PrepareItemCreationResult result) {
      _onNavigateCreateSalesOrder(context, result);
    },
    ...
  ),
),
_onNavigateCreateSalesOrder()
void _onNavigateCreateSalesOrder(
  BuildContext context,
  PrepareItemCreationResult result,
) {
  FlutterArtist.codeFlowLogger.addMethodCall(
    ownerClassInstance: this,
    currentStackTrace: StackTrace.current,
    parameters: null,
  );
  if (result.successForFirst) {
    SalesOrder96aDialog.openDialog(context);
  }
}
No ADS
No ADS