momentum 2.2.1 momentum: ^2.2.1 copied to clipboard
MVC pattern for flutter. Works as state management, dependency injection and service locator.
2.2.1 #
- Added missing runtimeType parameter for
service<T>()
method inMomentumController
.
2.2.0 #
- Improved services dependency injection where abstract classes are not recognized.
2.1.1 #
- Fixed hot reload issue for MomentumRouter.
2.0.1 #
- Fixed links in changelog.
- Follow analyzer suggestion for string interpolation.
2.0.0 #
- Null-safety migration.
- Fixed missing controllers in Momentum constructor not detected by MomentumBuilder.
- Fixed
Momentum.restart(...)
along withrestartCallback
parameter - throws null exception error. - Fixed
InjectService
type matching internally. - Exposed
InjectService
's service property instance. This is only for grabbing services usingInjectService
.InjectService<ApiService> injected; injected = Momentum.service<InjectService<ApiService>>(context); injected.value // the actual service is the `value`. this were previously private.
BREAKING CHANGE: Officially removed Router
class. Need to use the MomentumRouter
now. No api changes, just a simple rename to avoid conflict with flutter's Router class.
New features
- Added abstract callback
onReady()
for MomentumController. Read more about it here. - Added method
clearStateHistory()
for MomentumController. Reset the undo/redo state history. Read more about it here.
Internal updates
- Removed internal test related functions which are poorly written and undocumented.
getLastListenedState()
getLastEvent<T>()
- These functions are not meant for public or normal usage. But by any chance you actually use this in your projects. You'll need to revise your test files and follow the references below:
test\test_files\events_test.dart
- test sendEvent and listen.test\test_files\widgets\pages\todo_test.dart
- test addListener(...)
testMode
- removed because the original purpose was to test async methods with (mocked) sync implementations internally. Turns out there's a way to test async without pointlessly mocking sync. This was also undocumented and only meant to be used internally so you probably aren't using this.getController<T>()
- completely unnecessaryserviceForTest<T>
- completely unnecessary
- Rewrite the entire internal test folder.
1.3.6 #
- Fixed domain problem in documentation. (Should include
www.
)
1.3.5 #
- Fixed urls in the docs and readme.
- New momentum website address: https://www.xamantra.dev/momentum
1.3.4 #
- Fixed issue #40
- Starting from version 1.3.4, momentum no longer supports older versions of flutter.
1.3.3 #
- Deprecated
Momentum.of<T>(...)
. UseMomentum.controller<T>(...)
instead. - Deprecated
Momentum.getService<T>(...)
. UseMomentum.service<T>(...)
instead. - Deprecated
Router
. UseMomentumRouter
instead. - Deprecated
dependOn<T>()
. Usecontroller<T>()
instead. - Deprecated
getService<T>()
. Useservice<T>()
instead.
Note: Existing projects that still uses deprecated features will still work fine but they will be removed in the future and existing projects will break.
1.3.2 #
- Fixed Global lazy strategy not being applied to controllers #27
- Added
MomentumTester
tool for unit testing. - The
child
parameter inMomentum
constructor is no longer@required
. But it is still required for the app to run, it is only not required in unit testing.
1.3.1 #
- Fixed event bug where "sendEvent<T>()" was only called once but the "listen<T>" callback invokes twice.
- Implemented Make controllers in momentum builder optional #22
- Implemented Add try..catch while initing controllers and services #23
- Implemented Add a way (and or option) to allow lazy loading of controller's bootstrapping when called via Momentum.controller
1.3.0 #
Fixed changelog.md formatting after it got messed up with new pub.dev redesign.
1.2.9 #
Updated changelog.md to follow new pub.dev guidelines.
1.2.8 #
Router
now supports parameters.- Services now has dependency injection between each other.
- New
InjectService
class for services. - Momentum now initializes services first before anything else.
- No breaking changes in existing test files.
- No breaking changes in existing example projects.
- Refer to docs.
NOTE: If you encounter a bug with this update, please file an issue immediately on GitHub.
1.2.7 #
- Added testing guide in official docs: https://www.xamantra.dev/momentum/#/testing
1.2.6 #
- improve Momentum.restart function.
1.2.5 #
- fixed image links in docs
1.2.4 #
- The
pub.dev
package now excludeddocs/
andtest/
folders to speed upflutter pub get
for environment with limited internet access.
1.2.3 #
- Added
testMode
parameter onMomentum
for easier testing on project level. - Fixed bugs related to testing asynchronous code.
- Added more internal tests.
1.2.2 #
- Fixed
Router
error that happens whenpersistSave
is not specified. - Fixed
MomentumError
doesn't overridetoString()
so detailed error logs are not printed on the console.
1.2.1 #
1.2.0 #
- critical: fix
snapshot<T>()
where it throws a compile-time type error in older versions of flutter. - added and refactored test methods.
- added new internal tests.
1.1.9 #
1.1.8 #
- Changed license to BSD-3
- critical fix: reset() bug.
- fix config check bug in the "persistSave" parameter.
- (test) fixed dependOn
- added public methods for testability.
- Added internal tests.
TODO
- Add more internal tests.
- Find a workaround for issue #5
- Write docs for project-level testing.
- Refactor tests description/names.
1.1.7 #
Major changes:
- Persistent state.
- Persistent navigation/routing.
- Equatable support.
sendEvent<T>(...)
and.listen<T>(...)
.- Official Documentation: https://www.xamantra.dev/momentum/#/
Minor changes:
Momentum.controller<T>
is now the recommended way of getting a controller using context instead ofMomentum.of<T>
.Momentum.service<T>
is now the recommended way of getting a service using context instead ofMomentum.getService<T>
.enableLogging
now defaults tofalse
.
✔ No breaking changes.
1.1.6 #
- New function added:
Momentum.restart(...)
- Restart the app with a new momentum instance.
- To easily implement, in you
main.dart
create a method that returnsMomentum
instance.void main() { runApp(momentum()); // call the method here instead of instantiating the Momentum. } Momentum momentum() { return Momentum( child: MyApp(), controllers: [ LoginController(), SessionController()..config(lazy: false, enableLogging: true), TimerController()..config(maxTimeTravelSteps: 5), TimeclockController(), AppController()..config(lazy: false, enableLogging: true), SettingsController()..config(lazy: false), ], services: [ Router([ Login(), Home(), Settings(), LanguageSelection(), FontScale(), ]), ], enableLogging: false, onResetAll: (context, resetAll) async { await Momentum.of<SessionController>(context).clearSession(); resetAll(context); Router.goto(context, Login); }, ); }
- You can then call
Momentum.restart(...)
down the tree:Momentum.restart(context, momentum()); // call momentum() which is a top level function.
1.1.5 #
-
New feature added: Services.
-
Inject anything into momentum and use them down the tree inside widgets or controllers.
-
Example code:
// main.dart Momentum( controllers: [...], services: [ ApiService(), ], child: MyApp(), ... ) // *.controller.dart void loadUser() async { model.update(loadingUser: true); var apiService = getService<ApiService>(); var user = await apiService.getUser(); // load data from server. asynchronous model.update(loadingUser: false, user: user); }
1.1.4 #
- exposed MomentumModel.controller property.
1.1.3 - Breaking Changes #
bootstrap()
method is now synchronous only.- added
bootstrapAsync()
for separate asynchronous support. - For the execution order,
bootstrap()
gets called first thenbootstrapAsync()
. - added detailed logging for both
bootstrap()
andbootstrapAsync()
so you can see what gets executed first and the time it took.
1.1.2 #
- Fixed health check:
Fix lib/src/momentum_base.dart. (-1 points)
1.1.1 #
- New feature: Asynchronous
bootstrap()
method now supports loading widget usingappLoader
parameter onMomentum
root widget. IfappLoader
is not specified a default loading widget will be shown.- You have to turn lazy loading off to enable this feature.
- Lets say one of your controllers implements
bootstrap()
method asynchronously and it loads a data that takes seconds to finish:@override void bootstrap() async { // assuming we are loading some complex and big data here. var appSettings = await apiService.getAppSettings(); model.update(appSettings: appSettings); }
- Now, imagine
apiService.getAppSettings()
takes 3-5 seconds to load. Before yourMyApp()
gets loaded, momentum will await this bootstrap method and show a loading widget until it finishes. Means, you can now do anything you want with thebootstrap()
method synchronous or asynchronous. It is safe to callmodel.update(...)
in this method.
1.1.0 #
- Reformatted the whole readme, reduce the number of headings.
1.0.9 #
-
New feature:
dontRebuildIf
parameter forMomentumBuilder
.-
This method will be called after
model.update(...)
right before thebuilder
. -
isTimeTravel
is also provided that indicates if the model was updated by time travel methods.backward()
or.forward()
, returning it directly means you don't want to rebuild if an update was done with the time travel method. -
Two new properties were also added:
MomentumController.prevModel
andMomentumController.nextModel
which are properties from model history and their meaning is quite obvious. TheprevModel
is the previous state andnextModel
is the next state which will only have a value if you use.backward()
method. If you are on the latest snapshot of the modelnextModel
will be null. -
Take a look at this example, The widget is displaying a time format
HH: mm
andTimerController
ticks every500ms
for accuracy. We only need to rebuild if minute property is changed, that's where thedontRebuildIf
parameter comes.MomentumBuilder( controllers: [TimerController], dontRebuildIf: (controller, isTimeTravel) { var timer = controller<TimerController>(); var prevMinute = timer.prevModel.dateTime.minute; var currentMinute = timer.model.dateTime.minute; var minuteUnchanged = currentMinute == prevMinute; return minuteUnchanged; // don't rebuild the widget if "minute" is unchanged. }, builder: (context, snapshot) {...}, )
-
WARNING: This method is the same as any other
builder
orbuild
methods, do not callmodel.update(...)
or anything that callsbuild
method, for example,setState(...)
. You'll get an infinite loop.
-
1.0.8 #
- Major update:
- updated
onResetAll
to support widget operation before actually resetting all models. - improved README added lots of new content.
- updated
1.0.7 #
- fixed typos on the readme.
1.0.6 #
- updated readme added MomentumState listener section. and also fix typos.
1.0.5 #
- fix readme not properly displaying in pub.dev
1.0.4 #
- updated example project to link the correct
momentum
version frompub.dev
.
1.0.3 #
- updated readme, now most parts are covered.
1.0.2 #
- added example app.
1.0.1 #
- updated error message.
1.0.0 #
- Initial version.