Menu
CoddyTech

Provider: Consumer

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

כאן ספק הנתונים נוצר בתוך build של MyApp עצמה, ואותה build מבקשת את המנורה ממש מתחתיו. האפליקציה מציגה שגיאה: context שייך ל־MyApp, שנמצאת מעל ספק הנתונים, ווידג'ט יכול למצוא רק ספקי נתונים שנמצאים מעליו.

Consumer פותר את הבעיה. זהו ווידג'ט, ולכן הוא נמצא מתחת לספק הנתונים, וה־builder שלו מקבל context חדש ואת המודל עצמו:

Consumer<Lamp>(
  builder: (context, lamp, child) {
    return Text(lamp.isOn ? 'On' : 'Off');
  },
)

ה־builder מופעל מחדש בכל פעם שהמנורה קוראת ל־notifyListeners(), כמו ווידג'ט שעוקב אחריה. בתוכו אפשר לקרוא למתודות של המודל ישירות על lamp: onPressed: () => lamp.toggle().

Consumer גם בונה מחדש רק את מה שהוא עוטף, ולכן עטיפת החלק שמשתנה משאירה את שאר המסך ללא שינוי. ברוב האפליקציות תשתמשו ב־context.watch בווידג'ט משלו, ותבחרו ב־Consumer כשאתם נמצאים באותו build כמו ספק הנתונים.

challenge icon

אתגר

בינוני

האפליקציה נפתחת עם שגיאה. שים את חלקי המנורה בתוך Consumer:

  • עטוף את Column ב-Consumer<Lamp> והחזר את Column מתוך הבונה שלו.
  • בפנים, השתמש ב-lamp של הבונה עבור הסמל, הטקסט והכפתור.

נסו בעצמכם

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class Lamp extends ChangeNotifier {
  bool _isOn = false;

  bool get isOn => _isOn;

  void toggle() {
    _isOn = !_isOn;
    notifyListeners();
  }
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Lamp(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(title: const Text('Lamp')),
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(
                  context.watch<Lamp>().isOn ? Icons.lightbulb : Icons.lightbulb_outline,
                  size: 96,
                  color: context.watch<Lamp>().isOn ? Colors.amber : Colors.grey,
                ),
                Text(context.watch<Lamp>().isOn ? 'The lamp is on' : 'The lamp is off'),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: () => context.read<Lamp>().toggle(),
                  child: const Text('Switch'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
quiz iconבחנו את עצמכם

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

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

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