🧠 أولاً: ليش هذا الملف موجود أصلاً؟
🎯 المشكلة الأساسية
Supabase (أو أي API) يرجّع بيانات بهذا الشكل:
{
"id": 1,
"title": "hello",
"content": "test"
}Dartلكن Dart ما يفهم JSON مباشرة كـ Object.
🔥 الحل
نحوّل:
JSON (Map) → Object (NoteModel)Dart🧠 إذن هذا الملف وظيفته:
Translator (مترجم)Dart📁 الملف: note_model.dart
📄 الكود:
import '../../domain/entities/note.dart';
class NoteModel extends Note {
NoteModel({
required super.id,
required super.title,
required super.content,
});
factory NoteModel.fromJson(Map<String, dynamic> json) {
return NoteModel(
id: json['id'].toString(),
title: json['title'],
content: json['content'],
);
}
Map<String, dynamic> toJson() {
return {
'title': title,
'content': content,
};
}
}Dart🔍 الآن نشرح كل سطر بالتفصيل
🧱 1. import
import '../../domain/entities/note.dart';Dart🧠 شو يعني؟
نحن نستورد:
class NoteDart🎯 الهدف:
👉 نخلي Model يرث من Entity
🧱 2. class NoteModel extends Note
class NoteModel extends NoteDart🧠 أهم سطر في الملف كله
🎯 معناه:
NoteModel = Note + قدرات إضافية (JSON)Dart💡 ليش ورّثنا؟
بدل ما نكتب:
class NoteModel {
String id;
String title;
String content;
}Dartنستخدم:
extends NoteDart👉 إعادة استخدام الكود
👉 نفس الشكل تماماً
🧱 3. Constructor
NoteModel({
required super.id,
required super.title,
required super.content,
});Dart🧠 شرحها:
super.id
👉 يعني:
مرّر القيمة إلى الكلاس الأب (Note)Dart💡 يعني فعلياً:
NoteModel(...) → ينشئ Note أيضاًDart🧱 4. factory constructor 🔥🔥🔥
factory NoteModel.fromJson(Map<String, dynamic> json)Dart🧠 أهم مفهوم هنا: factory
🎯 شو يعني factory؟
👉 نوع خاص من constructor
❌ constructor عادي:
NoteModel(...)Dart✅ factory:
NoteModel.fromJson(...)Dart🧠 الفرق:
| constructor | factory |
|---|---|
| ينشئ object مباشرة | ممكن يتحكم بالإنشاء |
| بسيط | مرن |
| لا يعيد object موجود | ممكن يعيد object موجود |
🎯 لماذا نستخدم factory هنا؟
لأننا:
نحوّل JSON → ObjectDart🧠 الآن هذا السطر:
Map<String, dynamic> jsonDart🎯 شو يعني؟
هذا هو JSON بعد ما يتحول إلى Dart
💡 مثال:
{
"id": 1,
"title": "hello"
}Dartيصير في Dart:
{
"id": 1,
"title": "hello"
}Dart👉 نوعه:
Map<String, dynamic>Dart🧱 داخل fromJson
return NoteModel(
id: json['id'].toString(),
title: json['title'],
content: json['content'],
);Dart🧠 خطوة خطوة:
1️⃣
json['id']Dart👉 يأخذ القيمة من JSON
2️⃣
.toString()Dart👉 لأن Supabase أحياناً يرجع:
intDartونحن نريد:
StringDart3️⃣
return NoteModel(...)Dart👉 ينشئ object جديد
🔥 إذن:
fromJson = تحويل Map → ObjectDart🧱 5. toJson()
Map<String, dynamic> toJson()Dart🧠 عكس العملية
Object → JSONDart🎯 لماذا نحتاجها؟
عند الإضافة:
client.from('notes').insert(...)DartSupabase يريد:
{
"title": "...",
"content": "..."
}Dart🧠 داخلها:
return {
'title': title,
'content': content,
};Dart👉 أخذنا البيانات من object
👉 حولناها إلى JSON
❓ “أي Object يتحول؟”
الجواب:
NoteModel objectDartمثال:
final note = NoteModel(
id: "1",
title: "hello",
content: "test",
;Dartعند:
note.toJson()Dartيصير:
{
"title": "hello",
"content": "test"
}Dart🔁 الدورة الكاملة
📥 من Supabase:
JSON → Map → NoteModelDart📤 إلى Supabase:
NoteModel → Map → JSONDart💥 الفرق النهائي
| العملية | الدالة |
|---|---|
| JSON → Object | fromJson |
| Object → JSON | toJson |
🧠 لماذا طريقتين؟
لأن التطبيق يحتاج:
1️⃣ قراءة البيانات
select()Dart👉 نستخدم:
fromJsonDart2️⃣ إرسال البيانات
insert()Dart👉 نستخدم:
toJsonDart🔥 خلاصة قوية جداً
Model = طبقة ترجمة بين العالم الخارجي (JSON) والعالم الداخلي (Object)Dart