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