Provider: שיתוף מודל
חלק מהיחידה ניהול מצב במסלול ה-Flutter של Coddy. שיעור 9 מתוך 27.
הרמת מצב כלפי מעלה עובדת כשהווידג'טים קרובים זה לזה. כשצריך ערך בכל רחבי האפליקציה, בשני מסכים, בסרגל העליון או עמוק בתוך רשימה, צריך להעביר אותו דרך כל ווידג'ט שביניהם. Provider מייתר זאת. זוהי חבילה: אוסף של קוד שמייבאים באמצעות import 'package:provider/provider.dart';.
יש לה שלושה חלקים. ראשית, מודל: מחלקה שמחזיקה את הנתונים ו-extends ChangeNotifier. המתודות שלה משנות את הנתונים ואז קוראות ל-notifyListeners():
class CupCounter extends ChangeNotifier {
int _cups = 0;
int get cups => _cups;
void addCup() {
_cups++;
notifyListeners();
}
}שנית, ChangeNotifierProvider שממוקם גבוה בעץ יוצר את המודל פעם אחת ומעביר אותו לכל הווידג'טים שמתחתיו:
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => CupCounter(),
child: const MyApp(),
),
);
}שלישית, כל ווידג'ט שמתחתיו מבקש אותו: context.watch<CupCounter>() כדי להציג אותו, context.read<CupCounter>() כדי לקרוא למתודה. הכותרת והכפתור שלמטה מקבלים את אותו מונה, ולא מעבירים לאף אחד מהם שום דבר.
אתגר
בינוניפתחו את האפליקציה: היא מציגה שגיאה, כי הכותרת מבקשת CupCounter ואין שום דבר מעליה שמספק אחד כזה.
- ב־
main, עטפו אתMyAppבתוךChangeNotifierProviderשיוצרCupCounter.
נסו בעצמכם
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class CupCounter extends ChangeNotifier {
int _cups = 0;
int get cups => _cups;
void addCup() {
_cups++;
notifyListeners();
}
}
void main() {
runApp(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) {
return Scaffold(
appBar: AppBar(title: const CupsTitle()),
body: const Center(child: AddCupButton()),
);
}
}
class CupsTitle extends StatelessWidget {
const CupsTitle({super.key});
@override
Widget build(BuildContext context) {
final counter = context.watch<CupCounter>();
return Text('Cups: ${counter.cups}');
}
}
class AddCupButton extends StatelessWidget {
const AddCupButton({super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
context.read<CupCounter>().addCup();
},
child: const Text('Another cup'),
);
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה ניהול מצב
תרגלו בעצמכם: קומפיילר Flutter אונליין