Reputation: 1
I want to have few List
s, which I can provide using Provider
from provider package. I can add or remove elements from each of them. And elements of those lists are objects that can be changed too. I want my application to react to all of those changes.
For now I need to create separate class for each of those lists. Each of them has a field with List
and methods to access, remove or add its elements. This requires a lot of boilerplate and handling changes in fields of elements is hard.
// I would like to use ChangeNotifier here, but then I need to make all fields
// private, write getters and setters for them and assign them manually in
// constructor.
class Model {
int amount;
Model(this.amount);
}
class ModelService extends ChangeNotifier {
final models = <Model>[];
UnmodifiableListView<Model> get all => UnmodifiableListView(models);
int get length => models.length;
remove(Model model) {
models.remove(model);
notifyListeners();
}
add(Model model) {
models.add(model);
notifyListeners();
}
Model elementAt(int index) => models.elementAt(index);
elementChanged() => notifyListeners();
}
class ExampleWidget extends StatelessWidget {
@override
Widget build(BuildContext context) => Column(
children: [
RaisedButton(
child: Text('Add model'),
onPressed: () => Provider.of<ModelService>(context).add(Model(0)),
),
Expanded(
child: Consumer<ModelService>(
builder: (context, service, child) {
return ListView.builder(
itemBuilder: (context, index) {
if (index >= service.length) {
return null;
}
final model = service.elementAt(index);
return ListTile(
leading: IconButton(
icon: Icon(Icons.add),
onPressed: () {
model.amount++;
service.elementChanged();
},
),
title: Text(model.amount.toString()),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => service.remove(model),
),
);
},
);
},
),
),
],
);
}
Is there any simpler or more idiomatic way to handle such cases?
Upvotes: 0
Views: 444
Reputation: 2622
You can use Generics to make your object reusable:
class ModelService<Model> extends ChangeNotifier {
final models = <Model>[];
UnmodifiableListView<Model> get all => UnmodifiableListView(models);
int get length => models.length;
remove(Model model) {
models.remove(model);
notifyListeners();
}
add(Model model) {
models.add(model);
notifyListeners();
}
Model elementAt(int index) => models.elementAt(index);
elementChanged() => notifyListeners();
}
Something I would often do is inherit from that class and add extra logic to it: sorting, fetching, filtering, saving, etc. For example:
class TodoService extends ModelService<Todo> {
add(Todo model) {
super.add(model);
// save the list on disk
}
void setSearchText(String searchText) {
// apply search text on the models list
}
}
This way your widgets can become much simpler.
Upvotes: 1