Skip to content

Commit

Permalink
5.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Drawner committed Nov 12, 2024
1 parent e1aa805 commit 0abff89
Show file tree
Hide file tree
Showing 48 changed files with 520 additions and 285 deletions.
16 changes: 11 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@

## 5.6.0
November 15, 2024
- Introduce setBuilder() in every Controller. Will rebuild with every setState() call.
- Replacing stateSet(WidgetBuilder? builder) with the name, setBuilder in class, StateX and AppStateX
- class StateXController now includes mixin, ChangeNotifier and ListenableWidgetBuilderMixin

## 5.5.0
Octobter 14, 2024
October 14, 2024
- AppStateX class now has the notifyClientsInBuild parameter. Defaults to true.
Notify any dependencies when calling for a rebuild
This then notifies any dependencies when calling for a rebuild.
- The runInitAsync() function in every StateX object
now allows their initAsync() functions to be conditionally called wit every rebuild.
now allows their initAsync() functions to be conditionally called with every rebuild.

## 5.4.0
October 07, 2024
Expand All @@ -21,8 +27,8 @@ October 05, 2024

## 5.2.3
October 04, 2024
- Removed 'default' Error Handler mistakenly left in Production.
- Removed 'default' Error Widget Builder mistakenly left in Production.
- *BUGFIX* Removed 'default' Error Handler mistakenly left in Production.
- *BUGFIX* Removed 'default' Error Widget Builder mistakenly left in Production.
- User Error Handler, onError(), in part08_app_statex.dart.
- If onError() is not overridden, Flutter's own Error Handler is called.
- New getter, stateErrorHandled, can be set true by user.
Expand Down
31 changes: 15 additions & 16 deletions doc/03_controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ If not, you're actually impeding Flutter’s general functionality and degrading
The less that changes, the better.
Use the keyword, <i>final</i>, for variables assigned only once.
Better still, use the keyword, <i>const</i>, if you know the property's value
before compile-time will never change.
will never change before compile-time.
As your app runs, Flutter is calling those widgets over and over again.

<b>“There is no imperative changing of the UI itself (like widget.setText)—you change the state,
Expand All @@ -38,19 +38,18 @@ and the UI rebuilds from scratch.”</b>
— flutter.dev <a href="https://docs.flutter.dev/data-and-backend/state-mgmt/declarative">Start thinking declaratively</a>

Now, I suspect in the beginning, all your ‘mutable’ code was going into your State class.
A reasonable idea at first glance.
After all, you always want ready access to the State object and its <b>setState</b>() function.
However, that can make for a rather large and unmanageable Dart file
placing all the business logic and such under one State class.
I quickly found, more often than not, placing such code in a separate Dart file in a separate class made for a better approach.
However, that can make for a very large and unmanageable Dart file
placing all the business logic one State class.
I quickly found placing such code in a separate Dart file in a separate class made for a better approach.
You're explicitly separating the app's interface from its business rules.
Looking how Flutter implemented such an approach already using Controllers in widgets,
I created the 'State Object Controller' class.
Flutter already implemented such an approach using Controllers in many widgets,
I've done the same by creating the 'State Object Controller' class.

Again, however, when working with Flutter, you always need reliable access to a particular State object so to call its <b>setState</b>() function
(other developer's choose instead the StatefulElement’s <b>markNeedsBuild</b>() function).
Doing so ‘rebuilds’ that portion of the screen involving that State object and reflects the changes made.
That means the State Object controller would need access to its designated State object.
When working with Flutter, you always need reliable access to a particular State object so to call its <b>setState</b>() function
(other developer's instead call the StatefulElement’s <b>markNeedsBuild</b>() function).
This ‘rebuilds’ that portion of the screen involving that State object.
The State Object controller needs ready access to its designated State object.

<a target="_blank" rel="noopener noreferrer" href="https://miro.medium.com/v2/resize:fit:640/format:webp/1*x1qnWzfmhG8Z9WJVNYvL_Q.png"><img align="right" src="https://miro.medium.com/v2/resize:fit:640/format:webp/1*x1qnWzfmhG8Z9WJVNYvL_Q.png" width="253" height="286"></a>

Expand All @@ -59,8 +58,8 @@ That means the State Object controller would need access to its designated State
Through the course of an app’s lifecycle,
a controller can be assigned to any number of StateX objects.
A StateXController object works with ‘the last’ State object it’s been assigned to
but keeps a reference of any and all State objects it’s previously worked with in the Widget tree.
When a screen closes (i.e. the current StateX object is disposed of), the controller returns back to the previous StateX it was assigned to.
but keeps a reference all the State objects it’s previously worked with.
When a screen closes (i.e. the current StateX object is disposed of), the controller returns back to its previous StateX.
This allows, for example, for one controller to sustain the app’s business rules for the duration of the running app
conveying that logic across any number of screens (i.e. any number of StateX objects).

Expand All @@ -75,7 +74,7 @@ while its controllers are concerned with everything else.

<h2 id="example">Show By Example</h2>

Here is a gist file for you to download and follow along: <a href="https://gist.github.com/Andrious/e7d3ce3b8dcd5495978690a24ae5c3d6">statex_counter_app.dart</a>
Here is a gist file for you to download and follow along: <a href="https://gist.github.com/Andrious/c68d9f4edcc5e2344a3f50e49b269f2e">statex_counter_app.dart</a>
<br />
As you see in the first screenshot below, the traditional State class has been replaced with the class, StateX,
and takes in a StateXController object named, <i>YourController</i>.
Expand All @@ -87,11 +86,11 @@ However, note there’s no <b>setState</b>() function call.
It’s in the controller and called in the con.<b>onPressed</b>() function.

<div>
<a id="_StateXCounterPageState" target="_blank" rel="noopener noreferrer" href="https://github.com/AndriousSolutions/state_extended/assets/32497443/99061be8-b6f2-48b0-a33b-b4e0dc469b3e"><img src="https://github.com/AndriousSolutions/state_extended/assets/32497443/99061be8-b6f2-48b0-a33b-b4e0dc469b3e" width="48%" height="60%"></a>
<a id="_StateXCounterPageState" target="_blank" rel="noopener noreferrer" href="https://github.com/user-attachments/assets/57cf5ae6-081b-40e7-82a3-57cc8056ae8c"><img src="https://github.com/user-attachments/assets/57cf5ae6-081b-40e7-82a3-57cc8056ae8c" width="48%" height="60%"></a>
<a id="conBuildFunc" target="_blank" rel="noopener noreferrer" href="https://github.com/AndriousSolutions/state_extended/assets/32497443/a72a2131-66b4-420d-a50d-d968933293ad"><img src="https://github.com/AndriousSolutions/state_extended/assets/32497443/a72a2131-66b4-420d-a50d-d968933293ad" width="48%" height="60%"></a>
</div>

| [statex_counter_app.dart](https://gist.github.com/Andrious/e7d3ce3b8dcd5495978690a24ae5c3d6#file-statex_counter_app-dart-L24) | [statex_counter_app.dart](https://gist.github.com/Andrious/e7d3ce3b8dcd5495978690a24ae5c3d6#file-statex_counter_app-dart-L39) |
| [statex_counter_app.dart](https://gist.github.com/Andrious/c68d9f4edcc5e2344a3f50e49b269f2e#file-statex_counter_app-dart-L24) | [statex_counter_app.dart](https://gist.github.com/Andrious/e7d3ce3b8dcd5495978690a24ae5c3d6#file-statex_counter_app-dart-L39) |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------:|

<h2 id="setState">Set Control</h2>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// Copyright 2022 Andrious Solutions Ltd. All rights reserved.
// Copyright 2024 Andrious Solutions Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
///
/// Export libraries concerned with the App's 'Event Handling' (the Business Logic)
///
export 'package:example/src/another_app/home/controller.dart';
export 'package:example/src/another_app/home/gridview/controller.dart';
export 'package:state_extended/state_extended.dart' show StateXController;

export 'package:example/src/another_app/utils/controller.dart';
export '/src/another_app/home/controller_home.dart';

export 'package:state_extended/state_extended.dart' show StateXController;
export '/src/another_app/utils/controller_utils.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
/// The Controller for this app's Home Page StatefulWidget.
///
import '/src/another_app/controller.dart';
import '/src/another_app/controller_another_app.dart';

import '/src/another_app/view.dart';
import '/src/another_app/view_another_app.dart';

///
class HomeController extends StateXController {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
/// Export libraries concerned with the Home Page's 'Event Handling' (the Business Logic)
///
export 'package:example/src/another_app/home/controller/home_controller.dart';
export '/src/another_app/home/controller/home_controller.dart';

export 'package:example/src/another_app/home/inherited/controller.dart';
export '/src/another_app/home/gridview/controller_gridview.dart';

export '/src/another_app/home/inherited/controller_inherited.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
///
import 'dart:async';
import 'dart:convert' show json;

import 'package:example/src/another_app/home/gridview/view.dart';
import 'dart:convert' show json;

import 'package:example/src/controller.dart';
import 'package:http/http.dart' as http;

import 'package:example/src/view.dart';
import '/src/another_app/controller_another_app.dart';

import 'package:http/http.dart' as http;
import '/src/another_app/view_another_app.dart';

/// This is the 'image API' State Object Controller.
class ImageAPIController extends StateXController {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
/// All the SOC's used in this app's GridView widget
/// SOC stands for State Object Controllers.
///
export '/src/another_app/home/controller.dart';

export '/src/another_app/home/gridview/controller/image_api_controller.dart';

export '/src/another_app/home/gridview/images/controller.dart';
export '/src/another_app/home/gridview/images/controller_images.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
///
///
import 'package:example/src/controller.dart';
import '/src/another_app/controller_another_app.dart';

/// This SOC is associated with the Bird images and works with
/// InheritBird StatefulWidget and the InheritedWidget, _BirdInherited
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
///
///
import 'package:example/src/controller.dart';
import '/src/another_app/controller_another_app.dart';

///
class CatController extends InheritController {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
///
///
import 'package:example/src/controller.dart';
import '/src/another_app/controller_another_app.dart';

///
class DogController extends InheritController {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
///
///
import 'package:example/src/controller.dart';
import '/src/another_app/controller_another_app.dart';

///
class FoxController extends InheritController {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
/// This widget works with the free Bird API.
///
import 'package:example/src/another_app/controller.dart';
import '/src/another_app/controller_another_app.dart';

import 'package:example/src/another_app/view.dart';
import '/src/another_app/view_another_app.dart';

///
class RandomBird extends StatefulWidget {
Expand All @@ -28,4 +28,17 @@ class _RandomBirdState extends ImageAPIStateX<RandomBird> {
path: 'api/v2/random/animal/bird',
),
);

/// Place a breakpoint on this build() function and see how things work.
@override
// ignore: unnecessary_overrides
Widget build(BuildContext context) => super.build(context);

@override
// ignore: unnecessary_overrides
Widget buildF(BuildContext context) => super.buildF(context);

@override
// ignore: unnecessary_overrides
Widget builder(context) => super.builder(context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
///
/// This widget works with the free Cat API.
///
import 'package:example/src/another_app/controller.dart';
import 'package:example/src/another_app/view.dart';
import '/src/another_app/controller_another_app.dart';

import '/src/another_app/view_another_app.dart';

///
class RandomCat extends StatefulWidget {
Expand All @@ -27,4 +28,8 @@ class _RandomCatState extends ImageAPIStateX<RandomCat> {
path: 'api/v2/random/animal/cat',
),
);

/// Supply a 'splash screen' while the FutureBuilder is processing.
@override
Widget? onSplashScreen(BuildContext context) => const SplashScreen();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
/// This widget works with the free Dog API.
///
import 'package:example/src/another_app/controller.dart';
import '/src/another_app/controller_another_app.dart';

import 'package:example/src/another_app/view.dart';
import '/src/another_app/view_another_app.dart';

///
class RandomDog extends StatefulWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
/// This widget works with the free Fox API.
///
import 'package:example/src/another_app/controller.dart';
import '/src/another_app/controller_another_app.dart';

import 'package:example/src/another_app/view.dart';
import '/src/another_app/view_another_app.dart';

///
class RandomFox extends StatefulWidget {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///
///
///
export '/src/another_app/home/gridview/images/view.dart';
export '/src/another_app/home/gridview/images/view_images.dart';

export '/src/another_app/home/gridview/view/image_api.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
/// Contains the InheritedWidget for updating the Bird Image widgets.
///
import '/src/another_app/controller.dart';
import '/src/controller.dart';

import '/src/another_app/view.dart';
import '/src/view.dart';

///
class InheritBird extends StatefulWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
/// Stores the InheritedWidget used to update the Cat images.
///
import '/src/another_app/controller.dart';
import '/src/controller.dart';

import '/src/another_app/view.dart';
import '/src/view.dart';

/// This StatefulWidget stores an InheritedWidget
class InheritCat extends StatefulWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
/// This StatefulWidget works with the 'Dog' InheritedWidget
///
import '/src/another_app/controller.dart';
import '/src/controller.dart';

import '/src/another_app/view.dart';
import '/src/view.dart';

/// This StatefulWidget stores an InheritedWidget
class InheritDog extends StatefulWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
/// This StatefulWidget works with the Fox InheritedWidget.
///
import '/src/another_app/controller.dart';
import '/src/another_app/controller_another_app.dart';

import '/src/another_app/view.dart';
import '/src/another_app/view_another_app.dart';

/// This StatefulWidget stores an InheritedWidget
class InheritFox extends StatefulWidget {
Expand Down
5 changes: 2 additions & 3 deletions example/lib/src/another_app/home/view/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
///
/// The StatefulWidget representing the app's Home Page.
///
import '/src/another_app/home/view.dart';
import '/src/controller.dart';
import '/src/another_app/controller_another_app.dart';

import '/src/view.dart';
import '/src/another_app/view_another_app.dart';

/// The Home page
class HomePage extends StatefulWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
/// Export libraries concerned with the Home Page's Interface
///
export 'package:example/src/another_app/home/gridview/view.dart';
export 'package:example/src/another_app/home/gridview/view_gridview.dart';

export 'package:example/src/another_app/home/inherited/view.dart';
export 'package:example/src/another_app/home/inherited/view_inherited.dart';

export 'package:example/src/another_app/home/view/home_page.dart';
13 changes: 0 additions & 13 deletions example/lib/src/another_app/view.dart

This file was deleted.

14 changes: 14 additions & 0 deletions example/lib/src/another_app/view_another_app.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2024 Andrious Solutions Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ///
// /// Export libraries concerned with the App's 'View' (the Interface)

export 'package:flutter/material.dart';

export 'package:state_extended/state_extended.dart'show StateX;

export '/src/another_app/home/view_home.dart';

export '/src/view.dart' show SplashScreen;

Loading

0 comments on commit 0abff89

Please sign in to comment.