Une liste d’objets dans un modèle
Fait partie de la section Gestion d’état du Journey Flutter de Coddy. Leçon 14 sur 27.
Un modèle contient souvent une liste d’objets, et les objets eux-mêmes changent : une tâche est cochée. La règle reste la même : la modification passe par une méthode du modèle, et cette méthode appelle notifyListeners() :
class TaskList with ChangeNotifier {
final List<Task> _tasks = [Task('Buy milk'), Task('Call Sam')];
List<Task> get tasks => _tasks;
void toggle(Task task) {
task.done = !task.done;
notifyListeners();
}
}Modifier task.done depuis le widget modifierait aussi l’objet, mais aucun écouteur n’en serait informé, donc la case ne bougerait pas. Le modèle est le seul endroit où ses données sont modifiées, et le seul endroit qui le signale.
Remarque with. extends indique ce qu’est une classe, et une classe ne peut étendre qu’une seule autre classe. with ajoute des capacités à une classe, et tu peux en ajouter plusieurs. ChangeNotifier fonctionne dans les deux cas, donc class TaskList with ChangeNotifier équivaut à extends ChangeNotifier, et laisse extends libre pour autre chose.
Défi
MoyenAppuyer sur une tâche inverse task.done directement dans le widget, donc rien ne bouge à l’écran. Déplace le changement dans le modèle :
- Ajoute à
TaskListune méthodetoggle(Task task)qui inversedonepour la tâche et en informe les écouteurs. - Fais en sorte que
onChangedde la tuile l’appelle.
Essayez vous-même
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Task {
Task(this.title);
final String title;
bool done = false;
}
class TaskList with ChangeNotifier {
final List<Task> _tasks = [Task('Buy milk'), Task('Walk the dog'), Task('Call Sam')];
List<Task> get tasks => _tasks;
int get doneCount => _tasks.where((t) => t.done).length;
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => TaskList(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final list = context.watch<TaskList>();
return Scaffold(
appBar: AppBar(title: Text('${list.doneCount} of ${list.tasks.length} done')),
body: ListView(
children: [
for (final task in list.tasks)
CheckboxListTile(
title: Text(task.title),
value: task.done,
onChanged: (value) {
task.done = !task.done;
},
),
],
),
);
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Gestion d’état
3Provider
Provider : partager un modèleAppeler notifyListenersProvider : surveiller ou lireProvider : ConsumerDeux écrans, un modèleUne liste d’objets dans un modèlePlusieurs modèles : MultiProviderEntraînez-vous par vous-même : Compilateur Flutter en ligne