قائمة من الكائنات في نموذج
جزء من قسم إدارة الحالة في رحلة 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 متاحةً لشيء آخر.
التحدي
متوسطيؤدي النقر على مهمة إلى تغيير قيمة 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;
},
),
],
),
);
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس إدارة الحالة
3Provider
Provider: مشاركة نموذجاستدعاء notifyListenersProvider: المراقبة أم القراءةProvider: المستهلكشاشتان ونموذج واحدقائمة من الكائنات في نموذجعدة نماذج: MultiProviderتدرّب بنفسك: مترجم Flutter عبر الإنترنت