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?
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.