This is the 12th day of my participation in the August More Text Challenge. For details, see: August More Text Challenge
preface
In the previous article, We introduced the logic of using the Provider to transform the dynamic module to complete the deletion and detail pages. In fact, there are some awkward places in the renovation process, such as:
- We are in
DynamicModel
Class added_currentDynamic
It’s for the detail page, and this object is not really about the list, it’s just for the detail page. updateViewCount
This method is also related to a single dynamic class.
This causes our list page business to be coupled with the detail business, and if our add, update, and other dynamic related business are lost to the state management class, then the state management class will become bloated and violate the single responsibility principle. What to do at this time?
Naturally we think about splitting, yes, this is where we need to split the states of the different interfaces. In this article, we talk about nested state management, using the example of adding pages.
Add status management for the page
Let’s add a new state management class DynamicAddModel for the added page, and then move the business code from the previous added page into it. The specific properties and definitions are as follows:
Map<String, Map<String, Object>> _formData
: Form configurationMap
To dynamically configure the form for adding pages.File_imageFile
: The selected image file.DynamicEntity _currentDynamic
: Dynamic objects that are successfully added to the list to avoid refreshing the list again.handleTextFieldChanged(String formKey, String value)
: processing callback method for updating form data after the input box content changes;handleClear(String formKey)
: processing callback method when the input box clear button is clicked;handleImagePicked(File imageFile)
: processing callback method after picture selection is successful;Future<bool> handleSubmit()
: form submission method, which returns aFuture<bool>
Object that is returned on successtrue
, and return on failurefalse
. In order for the interface to do subsequent processing, here is to add data to the dynamic list after success, and return to the list page.
Add page modifications
With state management in place, adding pages is extremely easy. The difference is that we need to wrap the actual added page with a DynamicAddWrapper component so that we can use a Provider to manage the state of the added page at the parent of the added page. The code looks like this:
class _DynamicAdd extends StatelessWidget {
_DynamicAdd({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final watchState = context.watch<DynamicAddModel>();
final readState = context.read<DynamicAddModel>();
return Scaffold(
appBar: AppBar(
title: Text('Add dynamic'),
brightness: Brightness.dark,
),
body: DynamicForm(
watchState.formData,
readState.handleTextFieldChanged,
readState.handleClear,
'submit',
() {
readState.handleSubmit().then((success) {
if(success) { context.read<DynamicModel>().add(readState.currentDynamic); Navigator.of(context).pop(); }}); }, readState.handleImagePicked, imageFile: watchState.imageFile, ), ); }}class DynamicAddWrapper extends StatelessWidget {
DynamicAddWrapper({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
returnChangeNotifierProvider( create: (context) => DynamicAddModel(), child: _DynamicAdd(), ); }}Copy the code
Note that we have changed the add page _DynamicAdd class to an inner file class, because after adding state management, there must be a parent state management package component to use. Encapsulating the component as an inner class prevents errors from being reported when the component is used directly from the outside. For the _DynamicAdd class, we made the following changes:
- Move the business code into the state management class;
- The component by
StatefulWidget
Change toStatelessWidget
; - Replace the callback handling method of the form with the corresponding method of the state management object;
The use of nested states
In the dynamic add page, our processing code after successful submission is as follows:
readState.handleSubmit().then((success) {
if(success) { context.read<DynamicModel>().add(readState.currentDynamic); Navigator.of(context).pop(); }});Copy the code
The handleSubmit method of DynamicAddModel is called, and then the state management object of the dynamic list is called in the Then callback method of the Future. We use different levels of state management at the same time, that is, nested use. This is because the Provider itself is an encapsulation of InheritedWidget, so multi-level nesting can actually be used the same way as Widget nesting.
By taking away the state of the added page, does the entire UI layer of code feel much cleaner? For team collaboration, we can split the development work into business code and UI code after we agree on the INTERFACE at the UI layer, so as to achieve the division of labor and collaboration — but what boss would tell the App developer to write only the business or only the interface? All they want are gods like the one below!
conclusion
The code has been submitted to the: Status Management chapter source code. Using nested state management can further isolate the state management of different businesses in the same module, thus avoiding the bloated state management code and making the code conform to the single responsibility principle. However, if we look back at the code for dynamically adding and updating pages, we can see that 90% of the code is similar, and if this split feels a bit repetitive, what about sharing? In the next article, we will introduce the reuse of the Provider’s state management objects through the dynamic update page.
I’m an island user with the same name on wechat. This is a column on introduction and practice of Flutter.
👍🏻 : feel a harvest please point to encourage!
🌟 : Collect articles, convenient to read back!
💬 : Comment exchange, mutual progress!