Search code examples
flutterscoped-model

Flutter Scoped Model - Passing multiple Models


I've been playing with Scoped Model recently and was wondering if there's a better way to push multiple models onto the tree for use by children.

Suppose I have a 'AppModel' that's a composition of all the Models I need

class AppModel extends Model
{
  ModelA a = new ModelA();
  ModelB b = new ModelB();
  ModelC c = new ModelC();
}

I start by adding this model to the tree from main

runApp(ScopedModel<AppModel>(
    model: AppModel(),
    child: MaterialApp(
      title: 'MyApp',
      home: Home(),
    )),);

This causes the application to start at a Home page with an AppModel available in the tree

The Home page is a series of buttons each leading to another page which may use several of the models from AppModel

When a button is pressed I want to open the relevant page and pass the 'sub-models' that are needed from AppModel

Currently I have the onPressed for my buttons looking something like this, where I nest Scoped Models

() => Navigator.push(context, 
      MaterialPageRoute(builder: (context) => ScopedModel<ModelA>
          model: ScopedModel.of<AppModel>(context).a,
          child: ScopedModel<ModelB>(
             model: ScopedModel.of<AppModel>(context).b,
             child: PageAB())))))),

Within PageAB I can these access the relevant model via ScopedModel.of()

ScopedModel.of<ModelA>(context).modelAGet
ScopedModel.of<ModelA>(context).modelAFunc()

ScopedModel.of<ModelB>(context).modelBGet
ScopedModel.of<ModelB>(context).modelBFunc()

Is this the correct way to share (multiple) models? Or is there a more elegant solution?


Solution

  • That is one way you can do it. I use Mixins to compile different beahviours / features into the AppModel. Each model is responsible for a section/feature in the application. As an example I have a UserModel, SettingsModel and ContentModel

    They are all mixins on the Model class from the ScopedModel library

    mixin UserModel on Model {
     ...
    }
    mixin SettingsModel on Model {
     ...
    }
    mixin ContentModel on Model {
     ...
    }
    

    And then my main AppModel looks like this

    class AppModel extends Model with UserModel, SettingsModel, ContentModel {
      ...
    }
    

    This way I'm combining behaviours from different models, if you want to only expose the one type of model you can cast it and use that interface.

    I'm curently leaning towards this way where the Model files manages all the state for certain features and in those models I inject services which are singleton instance to share information between them if needed. These services perform all my actual business logic, Connecting to the API, serializing and compiling into contextual information for my app.