FlutterArtist Context Provider Views
FlutterArtist is structured into two clearly separated layers. Block, Scalar, FilterModel, and FormModel act as data models responsible for temporarily storing state, while ContextProviderView(s) are responsible for presenting these models and providing the necessary context on the user interface.
Each ContextProviderView is always associated with a specific data model. Its presence in the UI determines whether the model should load data and also defines the level of detail required for that data.
To better understand this mechanism, consider the following levels of data requirements represented by the components below.
BlockItemsView
When this component appears in the UI, it provides a Block context that requests the basic list of ITEM(s), which triggers the performQuery() method. If the component is not present, the corresponding queries are not executed, preventing unnecessary operations and saving system resources.
BlockItemDetailView
By default, this component provides a Block context and Item context. This ensures that performQuery() is invoked to load the list of ITEM(s). After the list is retrieved, one ITEM is selected as the current item, and the method performLoadItemDetailById() is then called to load the corresponding ITEM_DETAIL.
FormView
FormView implicitly provides Block context, Item context and Form context. This guarantees that the list of ITEM(s) is first loaded via performQuery(), and the ITEM_DETAIL of the current item is then retrieved through performLoadItemDetailById(). Once these foundational data are ready, the FormModel proceeds to load additional data required for editing in the form, such as option lists or dropdown data.
No ADS
The concept of Context Provider View is a core principle in FlutterArtist, emphasizing the philosophy that data should only be loaded when necessary and at the appropriate level of detail, thereby avoiding unnecessary consumption of system resources.
- FlutterArtist Debug UI Components Viewer
- FlutterArtist Lazy Loading (***)
1. BlockItemsView
BlockItemsView is a special UI component associated with a Block data model. Its presence in the UI triggers the data query for the corresponding Block. This component is used to display the list of ITEM(s) belonging to the Block on the user interface.

In the example below, Category08aListItemsView extends BlockItemsView and is responsible for displaying the ITEM(s) of Category08aBlock using a ListView. The data is retrieved from block.items, and each item is rendered through Category08aListItem.
Category08aListItemsView
class Category08aListItemsView
extends BlockItemsView<Category08aBlock> {
const Category08aListItemsView({required super.block, super.key});
@override
Widget buildContent(BuildContext context) {
return ListView(
padding: const EdgeInsets.all(5),
children: block.items
.map(
(item) => Category08aListItem(
categoryInfo: item,
selected: block.isCurrentItem(item),
onCategoryPressed: _onCategoryPressed,
),
)
.toList(),
);
}
...
}When BlockItemsView appears in the UI, the Block.performQuery() method of the corresponding Block is invoked to load the list of ITEM(s).
Category08aBlock.performQuery()
@override
Future<ApiResult<PageData<CategoryInfo>?>> performQuery({
required Object? parentBlockCurrentItem,
required EmptyFilterCriteria filterCriteria,
required SortableCriteria sortableCriteria,
required Pageable pageable,
}) async {
return await categoryRestProvider.query(pageable: pageable);
}BlockItemsView implicitly provides a Block context. This means it requests the associated Block to load data if the data state of that Block is not yet ready.
UI Component | Filter Context | Block Context | Item Context | Form Context |
BlockItemsView | true (Implicit) | true (Implicit) | false (Default) | false (Default) |
No ADS
BlockItemsView
abstract class BlockItemsView<BLOCK extends Block> extends StatelessWidget {
final BLOCK block;
final bool provideItemContext;
const BlockItemsView({
required this.block,
this.provideItemContext = false,
this.provideFormContext = false,
...
});
} 2. BlockItemDetailView
BlockItemDetailView is a UI component associated with a Block data model. Its presence in the UI triggers the query for the Block and sets one ITEM of the Block as the current item. The method Block.performLoadItemDetailById() is then called to load the ITEM_DETAIL based on the current ITEM’s ID.
- BlockItemDetailView is more powerful than BlockItemsView because its presence on the screen ensures that the Block is queried even if BlockItemsView is not present.
- BlockItemDetailView is intended to display a single ITEM_DETAIL. It should not be used to display a list of ITEM(s) of a Block, as doing so goes against the design philosophy of FlutterArtist.
Category08aBlock.performLoadItemDetailById()
@override
Future<ApiResult<CategoryData>> performLoadItemDetailById({
required int itemId,
}) async {
return await categoryRestProvider.find(categoryId: itemId);
}
Category08aItemDetailView
class Category08aItemDetailView extends BlockItemDetailView<Category08aBlock> {
const Category08aItemDetailView({super.key, required super.block});
@override
Widget buildContent(BuildContext context) {
// ITEM_DETAIL:
CategoryData? catData = block.currentItemDetail;
return Container(
padding: EdgeInsets.all(10),
// Other codes..
);
}
}- BlockItemDetailView implicitly provides a Block context, so it will request the Block to load data if it is not ready.
- BlockItemDetailView also implicitly provides an Item context, ensuring that the Block sets a current ITEM if the Block is not empty.
UI Component | Filter Context | Block Context | Item Context | Form Context |
BlockItemsView | true (Implicit) | true (Implicit) | false (Default) | false (Default) |
BlockItemDetailView | true (Implicit) | true (Implicit) | true (Implicit) | false (Default) |
3. BlockSectionView
BlockSectionView is a UI component associated with a Block data model. It is used to display any content related to the Block, such as descriptions, notes, or custom Button(s). BlockSectionView implicitly provides a Block context (which cannot be changed) and by default also provides an Item context, for which you can decide the initialization timing.
BlockSectionView
abstract class BlockSectionView<BLOCK extends Block> extends StatelessWidget {
final bool provideItemContext;
final BLOCK block;
const BlockSectionView({
required this.block,
this.provideItemContext = true,
super.key,
});
..
} No ADS
UI Component | Filter Context | Block Context | Item Context | Form Context |
BlockItemsView | true (Implicit) | true (Implicit) | false (Default) | false (Default) |
BlockItemDetailView | true (Implicit) | true (Implicit) | true (Implicit) | false (Default) |
BlockSectionView | true (Implicit) | true (Implicit) | true (Default) | false (Default) |
- BlockSectionView implicitly provides a Block context, meaning it will request the associated Block to load data if the Block’s data is not yet ready.
- By default, BlockSectionView also provides an Item context, which ensures that the Block sets a current ITEM if the Block is not empty.
BlockSectionView
abstract class BlockSectionView<BLOCK extends Block> extends StatelessWidget {
final bool provideItemContext;
final bool provideFormContext;
final BLOCK block;
const BlockSectionView({
required this.block,
this.provideItemContext = true,
this.provideFormContext = false,
super.key,
});
}4. BlockControlBar
BlockControlBar is a UI component associated with a Block. It provides a set of standard operational controls for the Block and its associated Form (if any). This component serves as the main interaction bar, allowing users to perform common actions such as refreshing the current ITEM, querying, creating, saving, deleting, navigating back, or opening debugging tools.
BlockControlBarConfig
class BlockControlBarConfig {
final bool allowRefreshButton;
final bool allowQueryButton;
final bool allowCreateButton;
final bool allowSaveButton;
final bool allowDeleteButton;
final bool allowBackButton;
final bool allowDebugFormModelViewerButton;
final bool allowDebugFilterCriteriaViewerButton;
final bool allowDebugButton;
const BlockControlBarConfig({
required this.allowRefreshButton,
required this.allowQueryButton,
required this.allowCreateButton,
required this.allowSaveButton,
required this.allowDeleteButton,
required this.allowBackButton,
required this.allowDebugFormModelViewerButton,
this.allowDebugFilterCriteriaViewerButton = false,
this.allowDebugButton = false,
});
}- BlockControlBar implicitly provides a Block context.
- BlockControlBar can also provide Item context and Form context if certain conditions are met.
BlockControlBar (**)
@override
bool get provideBlockContext {
return true;
}
@override
bool get provideItemContext {
if (block.formModel != null) {
if (config.allowSaveButton) {
return true;
}
}
return false;
}
@override
bool get provideFormContext {
if (block.formModel != null) {
if (config.allowSaveButton) {
return true;
}
}
return false;
}UI Component | Filter Context | Block Context | Item Context | Form Context |
BlockControlBar | true (Implicit) | true (Implicit) | Note (**) | Note (**) |
- FlutterArtist BlockControlBar (***)
5. FilterPanel
FilterPanel is a UI component associated with a FilterModel. It allows users to enter or select values for filter criteria.
FilterPanel provides a Filter context, meaning that when it appears on the screen, the associated FilterModel ensures that all necessary filter-related data is loaded, such as available criteria options.
A FilterModel can be shared by one or more Block(s) or Scalar(s). Therefore, context-aware components like BlockItemsView, BlockItemDetailView, or ScalarValueView that depend on the same FilterModel will automatically activate the Filter context as well.
UI Component | Filter Context |
FilterPanel | true (Implicit) |
- Ý tưởng thiết kế mô hình bộ lọc trong FlutterArtist
- FlutterArtist Filter - Ví dụ 1
- FlutterArtist FilterModelStructure ex1 (***)
6. SortPanel
SortPanel is a UI component associated with a SortModel. It allows users to select sorting criteria and direction for a Block.
No ADS
SortPanel provides a Block context, meaning that when it appears on the screen, it ensures the Block’s data is loaded and sorted according to the defined sorting rules.

UI Component | Filter Context | Block Context | Item Context | Form Context |
SortPanel | true (Implicit) | true (Implicit) | false (Default) | false (Default) |
- FlutterArtist Sorting Example
- FlutterArtist Multi Sort ex1 (***)
7. FormView
FormView is a UI component associated with a FormModel of a Block. It is responsible for rendering and managing the user interface of that Form.
FormView provides three contexts: Block, Item, and Form.
- Block context ensures that the Block’s data is loaded via Block.performQuery() to obtain the list of ITEM(s).
- Item context ensures that an ITEM is selected as the current item (if the Block is not empty) via Block.performLoadItemDetailById() to obtain ITEM_DETAIL.
- Form context ensures that the FormModel loads all necessary data for the Form, such as metadata, dropdown data, and additional related data.
UI Component | Filter Context | Block Context | Item Context | Form Context |
FormView | true (Implicit) | true (Implicit) | true (Implicit) | true (Implicit) |
- FlutterArtist Form - Ví dụ 1
- FlutterArtist Form Parent-child MultiOptFormProp (***)
8. ScalarValueView
ScalarValueView is a UI component associated with a Scalar data model. Its presence in the UI triggers data loading for this Scalar via the Scalar.performQuery() method. ScalarValueView displays the current value of the Scalar model on the interface.

No ADS
Note: A Scalar represents a single, read-only value. It does not maintain a list of ITEM(s), does not support selection, and does not define a current "ITEM" because its value is inherently the current value.
Scalar value example
{
"categoryCount": 3,
"employeeCount": 20,
"noteCount": 8,
"productCount": 31,
"supplierCount": 6,
"saleOrderCount": 301
}UI Component | Filter Context | Scalar Context |
ScalarValueView | true (Implicit) | true (Implicit) |
- FlutterArtist Scalar ex.1
9. ScalarSectionView
ScalarSectionView is a UI component associated with a Scalar data model. It is used to display additional content related to the Scalar, such as descriptions, notes, or custom action buttons.
ScalarSectionView implicitly provides a Scalar context, meaning that when it appears on the screen, it ensures the Scalar’s data has been loaded via Scalar.performQuery(), but it does not guarantee that the Scalar’s value is non-null.
Conceptually, ScalarSectionView and ScalarValueView are both used to display things related to a Scalar. The main difference lies in their intended use: ScalarValueView focuses on displaying the Scalar’s value, whereas ScalarSectionView is designed to display additional content or context related to the Scalar.
UI Component | Filter Context | Scalar Context |
ScalarSectionView | true (Implicit) | true (Implicit) |
10. ScalarControlBar
ScalarControlBar is a UI component associated with a Scalar. It provides a set of standard operational controls for the Scalar. This component serves as the main interaction bar, allowing users to perform common actions such as querying, navigating back, or opening debugging tools.
UI Component | Filter Context | Scalar Context |
ScalarControlBar | true (Implicit) | true (Implicit) |
11. StorageSectionView
StorageSectionView is a self-refreshing UI component that does not provide any data context.
Unlike components such as BlockItemDetailView or ScalarValueView, StorageSectionView does not automatically activate Block, Item, Form, or Scalar context. Therefore, if it is used to directly display content related to a Block or Scalar, there is no guarantee that the corresponding data has been loaded.
StorageSectionView is primarily designed as a layout container. It is commonly used to combine and arrange context-aware components like BlockItemsView, BlockItemDetailView, or ScalarValueView, allowing flexible UI structure while delegating data responsibilities to those components.
SomeStorageSectionView
class SomeStorageSectionView extends StorageSectionView {
const SomeStorageSectionView({super.key});
@override
Widget buildContent(BuildContext context) {
CategoryBlock block = ...;
ReportScalar scalar = ...;
return IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Card(child: CategoryBlockItemDetailView(block: block)),
),
Expanded(
child: Card(child: ReportScalarValueView(scalar: scalar)),
),
],
),
);
}
}No ADS