Menu
CoddyTech

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.

challenge icon

Défi

Moyen

Appuyer 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 à TaskList une méthode toggle(Task task) qui inverse done pour la tâche et en informe les écouteurs.
  • Fais en sorte que onChanged de 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;
              },
            ),
        ],
      ),
    );
  }
}
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur Flutter en ligne