titleController.text = widget.post.title; لماذا نستخدم كلمة widget هنا
هذه من أكثر النقاط التي تسبب حيرة للمبتدئين في Flutter.
لننظر أولاً إلى الكود:
class EditPostPage extends StatefulWidget {
final PostModel post;
const EditPostPage({
super.key,
required this.post,
});
@override
State<EditPostPage> createState() =>
_EditPostPageState();
}Dartهنا المتغير:
postDartموجود داخل:
EditPostPageDartوليس داخل:
_EditPostPageStateDartماذا يحدث عند فتح الصفحة؟
عندما نكتب:
EditPostPage(
post: post,
)Dartيتم إنشاء Widget جديدة.
هذه الـ Widget تحتوي:
final PostModel post;Dartثم ماذا؟
Flutter تنشئ State خاص بها:
_EditPostPageStateDartأصبح لدينا كائنان مختلفان:
الكائن الأول
EditPostPageDartويحتوي:
postDartالكائن الثاني
_EditPostPageStateDartويحتوي:
titleController
bodyController
isLoadingDartالمشكلة
داخل State نحاول الوصول إلى:
postDartلكن:
postDartغير موجودة داخل State.
هذا خطأ:
titleController.text =
post.title;Dartلأن State لا تملك متغيراً اسمه post.
كيف أصل للـ Widget من داخل State؟
Flutter توفر متغيراً جاهزاً اسمه:
widgetDartهذا المتغير يشير إلى:
EditPostPageDartالحالية.
لذلك:
widget.postDartتعني:
أعطني post الموجودة داخل EditPostPageDartصورة ذهنية
تخيل:
EditPostPage
│
├── post
│
└── _EditPostPageState
│
├── titleController
├── bodyController
└── isLoadingDartعندما يكون State بحاجة للوصول إلى:
postDartفهو يصعد إلى Widget:
widget.postDartمثال أبسط
class UserPage extends StatefulWidget {
final String name;
const UserPage({
required this.name,
});
@override
State<UserPage> createState() =>
_UserPageState();
}Dartداخل State:
class _UserPageState
extends State<UserPage> {
@override
void initState() {
super.initState();
print(widget.name);
}
}Dartهنا:
widget.nameDartتعني:
UserPage.nameDartلماذا لا نكتب this.post ؟
لأن:
thisDartتشير إلى:
_EditPostPageStateDartوليس إلى:
EditPostPageDartمثال:
print(this.runtimeType);Dartسيطبع:
_EditPostPageStateDartأما:
widget.runtimeTypeDartسيطبع:
EditPostPageDartقاعدة ذهبية
داخل:
StatefulWidgetDartأي متغير مرسل عبر Constructor مثل:
final PostModel post;Dartيتم الوصول إليه داخل State بواسطة:
widget.postDartوليس:
postDartوليس:
this.postDartلذلك هذا السطر:
titleController.text =
widget.post.title;Dartمعناه حرفياً:
خذ عنوان المنشور الموجود داخل EditPostPage
وضعه داخل TextField عند فتح الصفحة.Dart