• Stars
    star
    118
  • Rank 299,923 (Top 6 %)
  • Language
    Dart
  • License
    BSD 3-Clause "New...
  • Created over 4 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

MVC pattern for flutter. Works as state management, dependency injection and service locator.

MVC pattern for flutter. Works as state management, dependency injection and service locator.

Pub Version Test GitHub stars GitHub license GitHub last commit


Model View Controller

Here's a diagram describing the flow between the state (model), widget (view) and the logic (controller):

Both MomentumController and MomentumModel are abstract classes that needs to be implemented. A pair of model and controller is called a component. MomentumBuilder is simply a widget. This is used to listen to controllers for rebuilds and accessing models to display their values.

Example

If you want to see a full code example that runs. Visit the example tab for more details or you can visit the official webpage. Otherwise, if you only want to see a glimpse of how momentum works, read the Overview and FAQs below.

Advance Example: Listify (clone the repo and run the app, requires Flutter 2.0.0)

Overview

MomentumModel - the data or state. Must be Immutable.

class ProfileModel extends MomentumModel<ProfileController> {
  // ...

  final int userId;
  final String username;

  // ...
}

MomentumBuilder - the view or widget to display the state.

MomentumBuilder(
  controllers: [ProfileController], /// injects both `ProfileController` and `ProfileModel`.
  builder: (context, snapshot) {
    var profileState = snapshot<ProfileModel>(); /// grab the `ProfileModel` using snapshot.
    var username = profileState.username;
    return // some widgets here ...
  }
)

MomentumController - the logic to manipulate the model or state.

class ProfileController extends MomentumController<ProfileModel> {
  // ...

  Future<void> loadProfile() async {
    var profile = await http.get(...);
    // update the model's properties.
    model.update(
      userId: profile.userId,
      username: profile.username,
    );
  }

  // ...
}

FAQs

How to rebuild the widget?

Calling model.update(...) from inside the controller rebuilds all the MomentumBuilders that are listening to it.


How to access the model object?

It is automatically provided by MomentumController for you to use. Inside a controller class, you can access it directly. It's never null.


How to initialize the model or state?

By implementing the T init() method which is required by MomentumController. Like this:

class ShopController extends MomentumController<ShopModel> {

  @override
  ShopModel init() {
    return ShopModel(
      this, // required
      shopList: [],
      productList: [],
    );
  }
}

Can I access the model properties inside my controller?

Of course. The model object is already provided by MomentumController meaning you can also directly access its properties like this:

class ShopController extends MomentumController<ShopModel> {

  bool hasProducts() {
    return model.productList.isNotEmpty;
  }
}

Is there a special setup required for Momentum to run?

Yes, definitely. This is the required setup for Momentum in a flutter app:

void main() {
  runApp(momentum());
}

Momentum momentum() {
  return Momentum(
    child: MyApp(),
    controllers: [
      ProfileController(),
      ShopController(),
    ],
    // and more optional parameters here.
  );
}

Testing

Momentum is highly testable. This is how a basic widget testing for momentum would look like:

void main() {

  testWidgets('should display username', (tester) async {
    var profileCtrl = ProfileController();

    await tester.pumpWidget(
      Momentum(
        child: MyApp(),
        controllers: [profileCtrl],
      ),
    );
    await tester.pumpAndSettle();

    profileCtrl.updateUsername("johndoe");
    await tester.pumpAndSettle(); // ensure rebuilds

    expect(profileCtrl.model.username, "johndoe"); // unit check
    expect(find.text("johndoe"), findsOneWidget); // widget check
  });
}

Or you might not be a fan of widget testing and only want to test your components:

void main() {

  test('should display username', () async {
    var profileCtrl = ProfileController();

    var tester = MomentumTester(
      Momentum(
        controllers: [profileCtrl],
      ),
    );
    await tester.init();

    profileCtrl.updateUsername("johndoe");
    expect(profileCtrl.model.username, "johndoe"); // unit check
  });
}

Other optional features

  • Routing - Navigation system that supports persistence. The app will open the page where the user left off.
  • Event System - For showing dialogs, prompts, navigation, alerts.
  • Persistence State - Restore state when the app opens again.
  • Testing - Tests your widgets and logic. Built-in helper class for unit testing.

Momentum leverages the power of setState(..) and StatefulWidget behind the scenes. The feature Event System uses Stream.

Router issues

  • The router doesn't support named routes yet.
  • The parameter handling for router is slightly verbose. And might be complicated for some. But it works magically.
  • Needs to explicitly implement RouterPage widget in order to handle the system's back button.
  • (FIXED ✅) The router breaks after hot reload. Only a problem during development but it should work in normal execution.

API Reference

Visit the official webpage of momentum to browse the full api reference, guides, and examples.


Thanks for checking out momentum. I hope you try it soon and don't hesitate to file on issue on github. I always check them everyday.

More Repositories

1

listify

A flutter todo/task listing example app with advance state management using `Momentum` library.
Dart
20
star
2

relative_scale

RelativeScale is a simple custom sizing system for flutter widgets to achieve the same physical sizes across different devices.
Dart
19
star
3

xam-youtube-downloader

A simpe and lightweight YouTube video downloader built with Angular and PHP.
CSS
5
star
4

gh_trend

GitHub trending scraper for dart and flutter.
Dart
3
star
5

xam-youtube-downloader-api

This simple api is used for the xam-youtube-downloader angular project. But you can also used it on your own.
PHP
2
star
6

anime-player-with-discord-presence

It lets you open and watch an anime with your default video player and update your discord presence with the: Anime Name, Current Episode. and time elapsed.
C#
1
star
7

momentum-vscode

Boilerplate code generator for momentum controller and model class.
TypeScript
1
star
8

elapsed

Get time elapsed for asynchronous function in a single line of code.
Dart
1
star
9

flutter_relative_scale_example

The example app for relative_scale in flutter seen on the readme preview section.
Dart
1
star
10

enough_mail

Dart
1
star
11

mal-sense

A MyAnimeList script for extending the website's functionality and features.
JavaScript
1
star
12

token_signal_app

Get notified with crypto news. This is only a personal app and I never published it.
Dart
1
star
13

rikimaru

An anime discord bot that shows next episode countdown/schedule. I can synchronize your MAL account like a good boy. I can also let you subscribe to an anime and DM you when an episode is aired like an alarm clock.
TypeScript
1
star