Menu
CoddyTech

רשימת אובייקטים במודל

חלק מהיחידה ניהול מצב במסלול ה-Flutter של Coddy. שיעור 14 מתוך 27.

מודל מחזיק לעיתים קרובות רשימה של אובייקטים, והאובייקטים עצמם משתנים: מסמנים משימה. הכלל נשאר זהה: השינוי מתבצע באמצעות מתודה של המודל, והמתודה קוראת ל־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();
  }
}

שינוי task.done מתוך הווידג׳ט ישנה גם את האובייקט, אבל אף מאזין לא יקבל על כך הודעה, ולכן תיבת הסימון לא תזוז. המודל הוא המקום היחיד שמשנה את הנתונים שלו, וגם המקום היחיד שמודיע על כך.

שימו לב ל־with. extends מציין מה מחלקה היא, ומחלקה יכולה להרחיב מחלקה אחת בלבד. with מוסיף למחלקה יכולות נוספות, ואפשר להוסיף כמה כאלה. ChangeNotifier פועל בשתי הדרכים, ולכן class TaskList with ChangeNotifier שקול ל־extends ChangeNotifier, ומשאיר את extends פנוי למשהו אחר.

challenge icon

אתגר

בינוני

הקשה על משימה הופכת את task.done ישירות בתוך הרכיב, כך ששום דבר במסך לא זז. העבר את השינוי למודל:

  • הוסף ל־TaskList את המתודה toggle(Task task), שהופכת את הערך של done במשימה ומיידעת את המאזינים.
  • גרום ל־onChanged של האריח לקרוא לה.

נסו בעצמכם

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 iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה ניהול מצב

תרגלו בעצמכם: קומפיילר Flutter אונליין