Skip to content

Commit 4863e80

Browse files
committed
Add diagrams for generated methods & classes for model class.
1 parent 177b3d0 commit 4863e80

File tree

6 files changed

+163
-4
lines changed

6 files changed

+163
-4
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
title: Components
3+
slug: /generated-code/component-model
4+
sidebar_position: 6
5+
---
6+
7+
# Generated Code: Components
8+
9+
Similar to a [**Page**](pages-generated-code.md), when creating a component in FlutterFlow, it automatically generates two files: a `Widget` class and a `Model` class.
10+
11+
:::info[Prerequisites]
12+
This guide uses example of the generated code of the **[EcommerceFlow demo app](https://bit.ly/ff-docs-demo-v1)**. To view the generated code directly, check out the **[Github repository](https://github.com/FlutterFlow/sample-apps/tree/main/ecommerce_flow)**.
13+
:::
14+
15+
## ComponentModel class
16+
17+
`ComponentModel` classes are responsible for managing the state and behavior of individual components used within a page. These classes extend the `FlutterFlowModel` class, providing a consistent structure and shared functionality across all component models. This ensures that each component's state is isolated and reusable, making the app easier to maintain and scale.
18+
19+
The lifecycle of a `ComponentModel` and its associated widget class follows the same structure as a page. For more details, refer to the documentation on **[Generated Pages](pages-generated-code.md)**.
20+
21+
### onComponentLoad Action: Generated Code
22+
23+
When you define actions for the `onComponentLoad` action trigger of a component, these actions are added inside an `addPostFrameCallback` method within the page's `initState` method. This ensures that the actions are executed only after the initial widget tree is built.
24+
25+
```js
26+
@override
27+
void initState() {
28+
super.initState();
29+
_model = createModel(context, () => ProductListPageModel());
30+
31+
// On component load action.
32+
SchedulerBinding.instance.addPostFrameCallback((_) async {
33+
await _model.updateTotalCost(context);
34+
safeSetState(() {});
35+
});
36+
37+
}
38+
```
39+
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
---
2+
title: FlutterFlow Model
3+
slug: /generated-code/flutterflow-model
4+
sidebar_position: 4
5+
---
6+
7+
# FlutterFlow Model
8+
9+
The `FlutterFlowModel` class is an abstract class used in FlutterFlow to provide a unified and extensible structure for managing state and behavior of widgets (both pages and components). It encapsulates **initialization, state management,** and **disposal** logic, making it easier to handle the lifecycle of widgets and their models.
10+
11+
FlutterFlow automatically generates the `flutter_flow_model.dart` file, which contains the `FlutterFlowModel` class and utility methods like `wrapWithModel()` and `createModel()`.
12+
13+
The diagram below illustrates how these utility classes and methods are utilized in a widget or model class:
14+
15+
16+
![page-generated.png](imgs%2Fpage-generated.png)
17+
18+
When a component is added to your page (and every component you create [generates both a widget and a model class)](component-gen-code.md), the flow below explains how the utility classes are used when there is a child component:
19+
20+
![page-component-generated.png](imgs%2Fpage-component-generated.png)
21+
22+
<p></p>
23+
24+
Here’s a breakdown of the lifecycle of `FlutterFlowModel` class:
25+
26+
## Initialization
27+
Ensures the model is initialized **only once** and is tied to the `BuildContext` and the widget it is associated with.
28+
29+
```js
30+
abstract class FlutterFlowModel<W extends Widget> {
31+
// Initialization methods
32+
bool _isInitialized = false;
33+
void initState(BuildContext context);
34+
void _init(BuildContext context) {
35+
if (!_isInitialized) {
36+
initState(context);
37+
_isInitialized = true;
38+
}
39+
if (context.widget is W) _widget = context.widget as W;
40+
_context = context;
41+
}
42+
```
43+
44+
45+
## Widget & Context references
46+
47+
Provides references to the associated widget and its `BuildContext`.
48+
49+
```js
50+
// The widget associated with this model. This is useful for accessing the
51+
// parameters of the widget, for example.
52+
W? _widget;
53+
W? get widget => _widget;
54+
55+
// The context associated with this model.
56+
BuildContext? _context;
57+
BuildContext? get context => _context;
58+
```
59+
60+
`_widget` and `_context` (private fields) stores the widget and context references. `widget` and `context` (getters) are the public accessors for `_widget` and `_context`.
61+
62+
## Disposal
63+
64+
Manages the cleanup of resources when the model or widget is disposed.
65+
66+
```js
67+
bool disposeOnWidgetDisposal = true;
68+
void dispose();
69+
void maybeDispose() {
70+
if (disposeOnWidgetDisposal) {
71+
dispose();
72+
}
73+
// Remove reference to widget for garbage collection purposes.
74+
_widget = null;
75+
}
76+
```
77+
The `disposeOnWidgetDisposal` determines whether the model should be disposed when the widget is removed. This defaults to `true` for **pages** and `false` for **components** (as parent models typically manage their child components).
78+
79+
The `maybeDispose()` checks `disposeOnWidgetDisposal` before disposing. It removes the widget reference to aid garbage collection.
80+
81+
## Updates and Change Notification
82+
83+
Allows the model to notify the associated widget or parent component/page when updates occur.
84+
85+
```js
86+
// Whether to update the containing page / component on updates.
87+
bool updateOnChange = false;
88+
// Function to call when the model receives an update.
89+
VoidCallback _updateCallback = () {};
90+
void onUpdate() => updateOnChange ? _updateCallback() : () {};
91+
92+
FlutterFlowModel setOnUpdate({
93+
bool updateOnChange = false,
94+
required VoidCallback onUpdate,
95+
}) =>
96+
this
97+
.._updateCallback = onUpdate
98+
..updateOnChange = updateOnChange;
99+
100+
// Update the containing page when this model received an update.
101+
void updatePage(VoidCallback callback) {
102+
callback();
103+
_updateCallback();
104+
}
105+
```
106+
107+
## wrapWithModel()
108+
109+
The `wrapWithModel()` method in FlutterFlow links a model to a widget and its child widgets, allowing them to access and manage state. It wraps the widget with a Provider, making the model available throughout the widget tree.
136 KB
Loading
82.7 KB
Loading
96.1 KB
Loading

docs/generated-code/pages-generated-code.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
---
22
title: Pages
33
slug: /generated-code/page-model
4-
sidebar_position: 4
4+
sidebar_position: 5
55
---
66

77
# Generated Code: Pages
88

9-
When you create a new page in FlutterFlow, it automatically generates two files: a `Widget` class and a `Model` class. So if the name of the page you created is called ProductListPage, FlutterFlow generation backend will automatically create ProductListPageWidget class and ProductListPageModel class.
9+
When you create a new Page in FlutterFlow, it automatically generates two files: a `Widget` class and a `Model` class. So if the name of the page you created is called **ProductListPage**, FlutterFlow generation backend will automatically create **ProductListPageWidget** class and **ProductListPageModel** class.
1010

1111
:::info[Prerequisites]
1212
This guide uses example of the generated code of the **[EcommerceFlow demo app](https://bit.ly/ff-docs-demo-v1)**. To view the generated code directly, check out the **[Github repository](https://github.com/FlutterFlow/sample-apps/tree/main/ecommerce_flow)**.
@@ -16,6 +16,15 @@ This guide uses example of the generated code of the **[EcommerceFlow demo app](
1616

1717
The `PageModel` classes are responsible for managing the state of individual pages and initializing the components used in these Pages. These classes extend the `FlutterFlowModel` class, which provides a consistent structure and shared functionality across all page models.
1818

19+
The following diagram shows how FlutterFlow generates the model and widget class when you create a new Page in FlutterFlow:
20+
![page-generation-initial.png](imgs/page-generation-initial.png)
21+
22+
:::tip[FlutterFlow Model]
23+
To learn more about the utility classes and methods that FlutterFlow generates for all pages & components, see [**the FlutterFlowModel document**](flutterflow-model.md).
24+
:::
25+
26+
27+
1928
#### Managing Local State
2029

2130
A `PageModel` class typically holds local state fields specific to the page, which correspond to the **[Page State variables](../resources/ui/pages/page-lifecycle.md#page-state)**.
@@ -154,7 +163,7 @@ These functionalities are automatically added by FlutterFlow to ensure seamless
154163
155164
### onPageLoad Action: Generated Code
156165
157-
When you define actions for the `onPageLoad` action trigger of a Page, these actions are added inside an `addPostFrameCallback` method within the page's `initState` method. This ensures that the actions are executed only after the initial widget tree is built.
166+
When you define actions for the `onPageLoad` action trigger of a Page, these actions are added inside an `addPostFrameCallback` method within the page's `initState` method. This ensures that the **on Page Load** actions are executed after the widget is fully built and rendered. This avoids issues caused by trying to update the UI before it is ready.
158167
159168
```js
160169
@override
@@ -172,4 +181,6 @@ When you define actions for the `onPageLoad` action trigger of a Page, these act
172181
}
173182
```
174183
175-
The `addPostFrameCallback` ensures that onPageLoad actions are executed after the widget is fully built and rendered. This avoids issues caused by trying to update the UI before it is ready.
184+
:::tip[safe Set State]
185+
The `safeSetState` method is a custom implementation built on top of Flutter's `setState` method. It ensures that `setState` is only called when the widget is currently mounted, preventing potential runtime errors.
186+
:::

0 commit comments

Comments
 (0)