mydomain
No ADS
No ADS

FlutterArtist Deferring External Shelf Events (Ex1)

  1. Structure of the example
  2. openEndDrawerAndDeferExternalShelfEventsUntilClosed
  3. openDrawerAndDeferExternalShelfEventsUntilClosed
  4. openDialogAndDeferExternalShelfEventsUntilClosed
  5. Technical Insights
In FlutterArtist, by default, when you add, edit, or delete an ITEM, a signal is broadcasted to trigger subsequent reactions (via a Queue mechanism) on Block(s) and Scalar(s) across other Shelf(s).
However, executing multiple reactions can consume network and CPU resources. To optimize this, FlutterArtist allows you to defer events: notifications are placed in a waiting list instead of being sent immediately. Only when the source Dialog or Drawer/EndDrawer is closed will the entire list be aggregated (removing duplicate events) and sent simultaneously for a single processing cycle.
Aggregation Example:
  • 1st time: Event(ProductInfo), Event(ProductData)
  • 2nd time: Event(SupplierInfo)
  • 3rd time: Event(ProductInfo), Event(ProductData)
Final Aggregation:
  • Event(ProductInfo), Event(ProductData), Event(SupplierInfo)
Note: The example illustrated in this article (Demo71a) is an upgraded version from Demo27a (the version does not apply the event delay mechanism). You should refer to the Demo27a article linked below, as the example scenario and many of the underlying concepts will not be repeated in this content.
Demo71a:
No ADS
Demo71b:
  • Download FlutterArtist Demo

1. Structure of the example

2. openEndDrawerAndDeferExternalShelfEventsUntilClosed

To defer the event while an EndDrawer is open, you need to use the openEndDrawerAndDeferExternalShelfEventsUntilClosed() method. This method will open EndDrawer, and set up a mechanism to suspend ExternalShelfEvent events.
openEndDrawerAndDeferExternalShelfEventsUntilClosed()
FlutterArtist.storage
    .openEndDrawerAndDeferExternalShelfEventsUntilClosed(context);
Important note: For this mechanism to work, it is necessary that you actively update the state of the Drawer and EndDrawer with the FlutterArtist system through the onDrawerChanged and onEndDrawerChanged properties of Scaffold.
Scaffold
Scaffold(
  onEndDrawerChanged: (bool isOpened) {
      // IMPORTANT:
      FlutterArtist.storage.endDrawer.updateStatus(opened: isOpened);
  },
  onDrawerChanged: (bool isOpened) {
      // IMPORTANT:
      FlutterArtist.storage.drawer.updateStatus(opened: isOpened);
  },
  // ... Other Scaffold properties
);
No ADS
In case you use the flutter_artist_face library, update the state of Drawer and EndDrawer by overriding the two abstract methods onDrawerChanged() and onEndDrawerChanged().
MyFaceScreen
abstract class MyFaceScreen extends FaceScreen {
  const MyFaceScreen({super.key}); 

  @override
  void onDrawerChanged(bool isOpened) {
    // IMPORTANT:
    FlutterArtist.storage.drawer.updateStatus(opened: isOpened);
  }

  @override
  void onEndDrawerChanged(bool isOpened) {
    // IMPORTANT:
    FlutterArtist.storage.endDrawer.updateStatus(opened: isOpened);
  }
}
Going back to the example mentioned at the beginning of the article, here is the code that handles when the user clicks the "Edit Supplier" button:
_onPressEditSupplierBtn()
Future<void> _onPressEditSupplierBtn(BuildContext context) async {
  FlutterArtist.codeFlowLogger.addMethodCall(
    ownerClassInstance: this,
    currentStackTrace: StackTrace.current,
    parameters: null,
  );
  //
  SupplierInfo? supplierInfo = block.currentItem;
  if (supplierInfo == null) {
    return;
  }
  Coordinator coordinator = SingleSupplierEditCoordinator(
    supplierId: supplierInfo.id,
    config: CoordinatorConfig(),
    customNavigate: (BuildContext context, bool success) {
      if (success) {
        FlutterArtist.storage
            .openEndDrawerAndDeferExternalShelfEventsUntilClosed(context);
      }
    },
  );
  await coordinator.execute(context);
}
No ADS
And the processing code when the user clicks the "Create Supplier" button:
_onPressCreateSupplierBtn()
Future<void> _onPressCreateSupplierBtn(BuildContext context) async {
  FlutterArtist.codeFlowLogger.addMethodCall(
    ownerClassInstance: this,
    currentStackTrace: StackTrace.current,
    parameters: null,
  );
  //
  Coordinator coordinator = SingleSupplierCreationCoordinator(
    config: CoordinatorConfig(),
    customNavigate: (BuildContext context, bool success) {
      if (success) {
        FlutterArtist.storage
            .openEndDrawerAndDeferExternalShelfEventsUntilClosed(context);
      }
    },
  );
  await coordinator.execute(context);
}

3. openDrawerAndDeferExternalShelfEventsUntilClosed

Similarly, the openDrawerAndDeferExternalShelfEventsUntilClosed() method is used if you prefer a Drawer over an EndDrawer.

4. openDialogAndDeferExternalShelfEventsUntilClosed

For Dialog, the openDialogAndDeferExternalShelfEventsUntilClosed() method suspends all notifications until the user completes their task and closes the Dialog.
openDialogAndDeferExternalShelfEventsUntilClosed()
Future<DialogDeferralResult<V?>>
    openDialogAndDeferExternalShelfEventsUntilClosed<V>({
  required Future<V?> Function() openDialog,
})
Demo71b is an example illustrating the openDialogAndDeferExternalShelfEventsUntilClosed() method. Observing the animation above, you will see that when the user presses the "Create Supplier" button, a Dialog containing a form to create a new Supplier will appear.
Here, users perform consecutive operations: create, save, then continue to edit and save again. This entire process does not cause the list below to change immediately. Only after the Dialog is closed will the Supplier(s) list perform a query to update the data only once.

5. Technical Insights

Deferring ExternalShelfEvent essentially completely blocks individual notifications from reaching listeners. This applies to all, including those "listeners" that are clearly visible on the screen but are partially obscured by a Drawer/EndDrawer or Dialog.
Once the deferral ends (Drawer/EndDrawer or Dialog closes), a single aggregated event containing unique data types is dispatched. This mechanism ensures that even if a user manipulates data dozens of times within a Dialog, the underlying system only needs to "wake up" and refresh itself exactly once.
No ADS

FlutterArtist

Show More
No ADS