I need help creating the architecture for my application. I am using Flutter and scoped_model to maintain state.
It's an application that has a login, that displays news in one part of the application, and shows a photo gallery among others. I would like to split this entire thing into separate Models. LoginModel that holds Login state (like username, token, name etc.). NewsModel that contains news retrieved from the API. GalleryModel to hold names of photos etc. I am not sure if this is the best practice to maintain state using scoped_model.
For eg, what If a text box depends on both LoginModel and NewsModel? I am not sure, but I guess it's not possible to retrieve state from two separate models. Also, the main reason I am maintaining separate Models to hold state is that I don't want the Login part of the app to get refreshed when I bring news. I guess that's how it goes when I put the entire state in a single model.
The scoped_model
library is designed to work with multiple models in play at the same time. That's part of the reason that ScopedModel
and ScopedModelDescendant
are generics and have a type parameter. You can define multiple models near the top of your Widget tree using ScopedModel<LoginModel>
and ScopedModel<NewsModel>
and then consume those models lower in the tree using ScopedModelDescendant<LoginModel>
and ScopedModelDescendant<NewsModel>
. The descendants will go looking for the appropriate model based on their type parameter.
I knocked together a quick example. Here are the models:
class ModelA extends Model {
int count = 1;
void inc() {
count++;
notifyListeners();
}
}
class ModelB extends Model {
int count = 1;
void inc() {
count++;
notifyListeners();
}
}
And here's what I'm displaying in the app:
ScopedModel<ModelA>(
model: ModelA(),
child: ScopedModel<ModelB>(
model: ModelB(),
child: ScopedModelDescendant<ModelA>(
builder: (_, __, a) => ScopedModelDescendant<ModelB>(
builder: (_, __, b) {
return Center(
child: Column(
children: [
GestureDetector(
onTap: () => a.inc(),
child: Text(a.count.toString()),
),
SizedBox(height:100.0),
GestureDetector(
onTap: () => b.inc(),
child: Text(b.count.toString()),
),
],
),
);
},
),
),
),
)
It seems to be working just fine. A non-nested approach works as well:
ScopedModel<ModelA>(
model: ModelA(),
child: ScopedModel<ModelB>(
model: ModelB(),
child: Column(
children: [
ScopedModelDescendant<ModelA>(
builder: (_, __, model) => GestureDetector(
onTap: () => model.inc(),
child: Text(model.count.toString()),
),
),
SizedBox(height: 100.0),
ScopedModelDescendant<ModelB>(
builder: (_, __, model) => GestureDetector(
onTap: () => model.inc(),
child: Text(model.count.toString()),
),
),
],
),
),
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With