1

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?

Pablo Cegarra
  • 20,955
  • 12
  • 92
  • 110
user6635665
  • 337
  • 3
  • 15
  • I have already answered this question on this link, it can also help those who still consider combining multiple models in a single model. https://stackoverflow.com/a/56692571/3589715 – AlexPad Jun 20 '19 at 20:07

1 Answers1

9

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.

Filled Stacks
  • 4,116
  • 1
  • 23
  • 36
  • Thank you, this looks like an interesting alternative - I'll have to do some brushing up on mixins! – user6635665 Mar 01 '19 at 12:00
  • @user6635665 you're welcome :) here's a link to the article that helped me understand the reason for it's existence and how to use it. https://medium.com/flutter-community/dart-what-are-mixins-3a72344011f3 – Filled Stacks Mar 01 '19 at 12:07
  • @FilledStack I'm struggling with similar problem - could you share with me your PageAB's code so I can take a look how you retrieve ScopedModel in there? Do you pass ScopedModel in PageAB's constructor ? – Matt May 10 '19 at 12:57
  • 1
    @Matt I did a full video here on ScopedModel. In short I use get_it to inject the model where it's needed. https://youtu.be/JsjDLHxGz4M – Filled Stacks May 10 '19 at 17:55
  • will check it out today, tkank you! :) – Matt May 13 '19 at 07:41