Menu
CoddyTech

Lista obiektów w modelu

Część sekcji Zarządzanie stanem ścieżki Flutter w Coddy. Lekcja 14 z 27.

Model często przechowuje listę obiektów, a same obiekty się zmieniają: zadanie zostaje odhaczone. Zasada pozostaje taka sama: zmiana przechodzi przez metodę modelu, a metoda wywołuje 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();
  }
}

Zmiana task.done z poziomu widżetu również zmieniłaby obiekt, ale żaden odbiorca nie zostałby o tym powiadomiony, więc pole wyboru by się nie zmieniło. Model jest jedynym miejscem, które zmienia swoje dane, i jedynym miejscem, które o tym informuje.

Zwróć uwagę na with. extends określa, czym jest klasa, a klasa może dziedziczyć tylko po jednej innej klasie. with dodaje do klasy dodatkowe możliwości, a możesz dodać ich kilka. ChangeNotifier działa na oba sposoby, więc class TaskList with ChangeNotifier jest równoważne extends ChangeNotifier i pozostawia extends wolne do użycia w innym celu.

challenge icon

Wyzwanie

Średni

Dotknięcie zadania przełącza task.done bezpośrednio w widżecie, więc nic na ekranie się nie przesuwa. Przenieś tę zmianę do modelu:

  • Dodaj do TaskList metodę toggle(Task task), która przełącza done zadania i powiadamia nasłuchujących.
  • Spraw, aby onChanged kafelka ją wywoływało.

Spróbuj swoich sił

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 iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Zarządzanie stanem

Poćwicz samodzielnie: Kompilator Flutter online