mvcprovider

Create a simple MVC architecture based on the Provider package.

Getting Started

Everybody need to create a counter module, and of course you need it too.

STEP 1

First, define your very complex model :

    class MyCounterModel extends Model {

      int count = 0;

    }

STEP 2

Then define a controller that will increment the count property with a lot of mathematics operations :

    class MyCounterCtrl extends Controller<MyCounterModel> {
    
      void increment() {
        model.count++;
        notifyListeners();
      }
    
      /*
      // Uncomment if needed
      // Init is called one time before view's first render
    
      @override
      Controller init(BuildContext context, MyCounterModel model, Map<Type, dynamic> dependencies) {
        super.init(context, model, dependencies);
    
        // Do some cool things here that you need to do before
        // using this controller or rendering the view
    
        // Like it'll be explained in STEP 4 :
        // You can also access here to some globals providers
        // (that have been injected at module level)
        // with the method : get<MyProviderClass>()
    
        return this;
      }
      */
    
    }

For now, you have an amazing method increment that will increment (no ?! really ??) you're model's property count and then call notifyListener (a method inherited from the mother class Controller which inherit from her mother class ChangeNotifier) to refresh the view.

STEP 3

But to refresh the view. You need a view. Here it is :

    class MyCounterView extends View<MyCounterModel, MyCounterCtrl> {
    
      @override
      Widget build(BuildContext context, [Widget child]) {
        super.build(context);
    
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("Counter : ${model.count}"),
            RaisedButton(
                child: Text("Increment"),
                onPressed: ctrl.increment,
            )
          ]
        );
      }
    }

It's a bit complicated view. I'll explain : it's a text on top of a button.

Like you can see the text display our model's property count and the button execute our controller's method increment when pressed.

STEP 4

In order to make the magic happen you'll need to link these three entities together, I decided that this fusion will be called a Module but you can call this Roberto or anything else if you prefer.

Here is our module :

    class MyCounterModule extends Module<MyCounterModel, MyCounterView, MyCounterCtrl> {
    
      final MyCounterModel model = MyCounterModel();
      final MyCounterView view = MyCounterView();
      final MyCounterCtrl ctrl = MyCounterCtrl();
    
      /*
      // Uncomment if needed
      // To keep your controller code clean you can add here some globals
      // providers that you need and so they will be injected in the "init"
      // method of the "Controller" class and available in your controller or
      // your view by calling for example : "get<MyProviderClass1>()"
    
      final Map<Type, dynamic> dependencies = {
        MyProviderClass1: (_) => Provider.of<MyProviderClass1>(_, listen: false)
        MyProviderClass2: (_) => Provider.of<MyProviderClass2>(_, listen: false)
        MyProviderClass3: (_) => Provider.of<MyProviderClass3>(_, listen: false)
      };
      */
    
    }

STEP 5

At this point if you're a good developer you should have a folder named mycounter with 4 files inside :

The module my.counter.dart The model my.counter.model.dart The view my.counter.view.dart The controller my.counter.ctrl.dart

You can also have only one file with all your code inside but it's mean you're a bad developer ;)

To test you newly counter feature in your app just call your widget MyCounterModule() Example in your main.dart :

    void main() => runApp(AmazingSample());
    
    class AmazingSample extends StatelessWidget {
      // This widget is the root of this amazing package sample.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'MVC Provider counter demo',
          home: MyCounterModule(),
        );
      }
    }

Libraries

mvcprovider