Menu
CoddyTech

כמה מודלים: MultiProvider

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

כדאי להקצות לכל מודל תפקיד אחד: הניקוד במחלקה אחת, והחיים במחלקה אחרת. קל לקרוא מודלים קטנים, ווידג׳ט עוקב רק אחרי מה שהוא צריך. אפליקציה עם כמה מודלים זקוקה לכמה ספקים.

אפשר לקנן אותם, ספק אחד בתור הילד של הבא אחריו, אבל הקוד נדחק ימינה עם כל מודל. MultiProvider מקבל רשימה שטוחה במקום זאת:

runApp(
  MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (context) => Score()),
      ChangeNotifierProvider(create: (context) => Lives()),
    ],
    child: const MyApp(),
  ),
);

לספקים שברשימה אין child משלהם: MultiProvider עורם אותם בשבילך ומציב את child מתחת לכולם. כל ווידג׳ט שמתחתיהם יכול לעקוב אחר כל אחד מהמודלים או לקרוא אותו, לפי הטיפוס שלו: context.watch<Lives>().

challenge icon

אתגר

קל

דף המשחק עוקב אחר שני מודלים, Score ו־Lives, אבל main מספק רק את הניקוד, ולכן האפליקציה מציגה שגיאה.

  • החליפו את הספק ב־main ב־MultiProvider שמספק את שני המודלים.

נסו בעצמכם

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

class Score extends ChangeNotifier {
  int _points = 0;

  int get points => _points;

  void hit() {
    _points += 10;
    notifyListeners();
  }
}

class Lives extends ChangeNotifier {
  int _left = 3;

  int get left => _left;

  void miss() {
    if (_left > 0) {
      _left--;
      notifyListeners();
    }
  }
}

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => Score(),
      child: const MyApp(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: GamePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final points = context.watch<Score>().points;
    final lives = context.watch<Lives>().left;
    return Scaffold(
      appBar: AppBar(title: Text('Lives: $lives')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('Points: $points', style: const TextStyle(fontSize: 40)),
            const SizedBox(height: 16),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                ElevatedButton(
                  onPressed: () => context.read<Score>().hit(),
                  child: const Text('Hit'),
                ),
                const SizedBox(width: 16),
                ElevatedButton(
                  onPressed: () => context.read<Lives>().miss(),
                  child: const Text('Miss'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
quiz iconבחנו את עצמכם

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

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

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