رفرفة: كيفية القيام CRUD مع بوستجرس؟ الجزء 2

سأشارك اليوم بعض الموضوعات المثيرة مثل:

  • كيفية بناء RESTful api على خادم الويب باستخدام Dart و Aqueduct مع دمج Postgresql.
  • كيفية إنشاء تطبيق جوال Flutter وأداء وظائف CRUD الأساسية مع تطبيق Aqueduct. أنت هنا

من المشاركة السابقة ، قمت بمشاركة كيفية إعداد خادم الويب الخاص بك لتطبيق RESTful api باستخدام Aqueduct مع Postgresql. في هذا المنشور ، سنبدأ في إنشاء تطبيق رفرفة للتفاعل مع تطبيق الويب الخاص بنا.

كيفية إعداد مشروع رفرفة

إنشاء مكالمة مشروع Flutter جديدة flutter_crud_demo. إذا كنت تستخدم Visual Studio Code ، يمكنك إنشاء مشروع جديد عن طريق View> Command Pallete> Flutter New Project> أدخل اسم المشروع> حدد دليل لحفظ مشروعك. عند الانتهاء من تهيئة مساحة العمل ، احذف widget_test.dart وأفرغ محتوى main.dart.

قراءة وظيفة

باني المستقبل

يسمح لنا باني المستقبل بتقديم عرض قائمة بمجرد أن نحصل على قائمة البيانات الخاصة بنا بشكل غير متزامن. باني المستقبل له معلمتان ، أحدهما المستقبل وهي الطريقة المستقبلية التي نستخدمها لاسترداد قائمة البيانات والآخر هو باني وهو ما نريد أن نبني عليه مع البيانات. يتيح لنا استخدام أداة بناء المستقبل أن نعرض للمستخدم CircularProgressIndicator قبل أن تصبح البيانات جاهزة ويعرض ListView عند الانتهاء من عملية السحب. في هيكل السقالة الخاص بنا ، استبدل بالكود التالي.

هيكل: حاوية جديدة (
  تابع: FutureBuilder الجديد > (
    المستقبل: getAll () ،
    المنشئ: (السياق ، لقطة) {

      if (snapshot.hasData) {
        إرجاع ListView.builder الجديد (
          itemCount: snapshot.data.length ،
          itemBuilder: (السياق ، الفهرس) {
            إرجاع عمود جديد (
              crossAxisAlignment: CrossAxisAlignment.start ،
              الأطفال:  [
                نص جديد (snapshot.data [الفهرس] .name ،
                  النمط: TextStyle جديد (fontWeight: FontWeight.bold)) ،
                مقسم جديد ()
              ]
            )؛
          }
        )؛
      } if if (snapshot.hasError) {
        إرجاع نص جديد ("$ {snapshot.error}") ؛
      }

      // افتراضيا ، اظهار التحميل الدوار
      إرجاع CircularProgressIndicator () جديد ؛
    }،
  )،
)،

بعد ذلك ، نحتاج إلى تطبيق طريقة getAll () لاسترداد قائمة الأبطال من خادم الويب الخاص بنا. ترجع طريقتنا قائمة نوع Futureof للبطل. داخل الوظيفة ، ندعو و awaithttp.get (_heroesUrl). الانتظار يسمح لنا بانتظار الرد قبل المتابعة إلى السطر التالي. تحتاج الدالة getAll () إلى أن تكون متزامنة لتكون قادرة على استخدام تنتظر داخل الأسلوب. من الرد ، نقوم باسترداد رسالة النص الأساسي وتحويلها إلى

المستقبل > getAll () async {
  الرد النهائي = انتظار http.get (_heroesUrl) ؛
  طباعة (response.body)؛
  سرد responseJson = json.decode (response.body.toString ()) ؛
  قائمة  userList = createHeroesList (responseJson) ؛
  إرجاع userList ؛
}

نحن بحاجة إلى استيراد بعض المكتبات لبعض وظائف المساعد.

استيراد "دارت: تحويل" ؛
import 'dart: async'؛
استيراد "الحزمة: http / http.dart" كـ http؛

لنقم بإنشاء اتصال هاتفي مع Hero. تأخذ هذه الفئة عددًا صحيحًا للمعرف والسلسلة كاسم.

فئة بطل {
  Hero ({this.id، this.name})؛
  معرف int النهائي.
  اسم السلسلة
}

داخل الفئة _MyHomePageState ، أضف const ثابت _heroesUrl لاحتواء عنوان url الخاص بالمضيف المحلي.

static const _heroesUrl = 'http: // localhost: 8888 / heroes'؛

لنشغل تطبيق الرفرفة. تذكر أيضًا بدء تشغيل تطبيق خادم الويب الخاص بك باستخدام أمر خدمة القنوات.

يمكننا الحصول على قائمة الأبطال في تطبيق Flutter الخاص بنا

حذف وظيفة

من هنا فصاعدًا ، سنقدم تعدادًا لتخزين حالة أي طلب http. يجب أن يُرجع أي طلب http نوع HttpRequestStatus.

التعداد HttpRequestStatus {
  لم تفعل،
  فعله،
  خطأ
}

Dismissible

سنقوم بتنفيذ التمرير السريع للحذف وهو نمط شائع جدًا موجود في تطبيقات الأجهزة المحمولة. للقيام بذلك ، سنقوم بتبديل العمود بـ Dismissible كما هو موضح أدناه. نطلب بعد ذلك حذف البطل بمعرفه في المعلمة onDississed. تقوم الدالة deleteHero بإرجاع مستقبل وهو httpRequestStatus. إذا تم تنفيذ الحالة ، فسنطلب إعادة رسم الشاشة باستخدام setState ().

إرجاع ListView.builder الجديد (
    itemCount: snapshot.data.length ،
    itemBuilder: (السياق ، الفهرس) {
      var item = snapshot.data [الفهرس] ؛

      عودة مفهومة (
        المفتاح: المفتاح (item.id.toString ()) ،
        onDisseded: (direction) async {
          httpRequestStatus = في انتظار deleteHero (item.id) ؛
          if (httpRequestStatus == HttpRequestStatus.DONE) {
            setState (() {
              snapshot.data.removeAt (رقم قياسي).
            })؛
          }
        }،
        الخلفية: حاوية (اللون: Colors.red) ،
        تابع: ListTile (العنوان: نص ('$ {item.name}')) ،
      )؛
    })؛

طريقة الحذف هي كما يلي

الحذف في المستقبل Hero (int id)
  httpRequestStatus = HttpRequestStatus.NOT_DONE؛
  عنوان url النهائي = '$ _heroesUrl / $ id' ؛
  الرد النهائي = تنتظر http.delete (url ، الرؤوس: _headers) ؛
  إذا (response.statusCode == 200) {
    طباعة (response.body.toString ())؛
    httpRequestStatus = HttpRequestStatus.DONE؛
  } آخر {
    httpRequestStatus = HttpRequestStatus.ERROR؛
  }

  إرجاع httpRequestStatus ؛
}
انتقد لحذف البطل

إضافة وظيفة

دعنا نضيف أيقونة عنصر واجهة مستخدم تحت AppBar للسماح للمستخدم بإضافة البطل.

appBar: AppBar الجديد (
  العنوان: نص جديد ('Flutter CRUD Demo') ،
  الإجراءات:  [
    IconButton (
      أيقونة: أيقونة (Icons.add) ،
      onPressed: _addHeroService ،
      تلميح الأدوات: "إضافة بطل جديد" ،
    )
  ]،
)،

في _addHeroService ، ندعو _openDialogAddHero لدفع شاشة جديدة لإدخال المستخدم على اسم البطل. تُرجع هذه الطريقة اسمًا جديدًا للبطل الذي سنقوم بعد ذلك باستدعاء createHero به وإذا تم تحديث اسم البطل بنجاح ، فسوف ندعو setState () لإعادة رسم الشاشة.

باطل _addHeroService () غير متزامن
  اسم السلسلة = انتظار _openDialogAddHero ()؛
  HttpRequestStatus httpRequestStatus = ننتظر createHero (الاسم) ؛
  if (httpRequestStatus == HttpRequestStatus.DONE) {
    setState (() {
      
    })؛
  }
}

دعنا نضيف رؤوس ثابتة ثابتة لتخزين نوع رأس http.

static final _headers = {'Content-Type': 'application / json'}؛

فيما يلي الكود لإرسال طلب إنشاء بطل جديد إلى تطبيق خادم الويب.

المستقبل createHero (اسم السلسلة) المتزامن {
  httpRequestStatus = HttpRequestStatus.NOT_DONE؛
  الرد النهائي = في انتظار http.post (_heroesUrl ،
      headers: _headers، body: json.encode ({'name': name}))؛
  إذا (response.statusCode == 200) {
    طباعة (response.body.toString ())؛
    httpRequestStatus = HttpRequestStatus.DONE؛
  } آخر {
    httpRequestStatus = HttpRequestStatus.ERROR؛
  }

  إرجاع httpRequestStatus ؛
}
يمكننا إضافة بطل جديد الآن

وظيفة التحديث

أخيرًا ، تبقى لدينا وظيفة أخيرة وهي القدرة على تحديث اسم البطل. نريد أن ينقر المستخدم على البطل الحالي لتحديث الاسم. لهذا ، نضيف onTap داخل ListTile والذي يستدعي الأسلوب _updateHeroService ، ويمرر معرف البطل واسمه في فهرس القائمة. على غرار _addHeroService الذي يسترجع الاسم من مربع الحوار المنبثق وينتقل إلى updateHero. يتم بعد ذلك إعادة رسم الشاشة في حالة نجاح updateHero.

مستقبل _updateHeroService (int id ، اسم السلسلة) المتزامن {
  تم تحديث السلسلة = انتظار _openDialogUpdateHero (المعرف ، الاسم) ؛
  HttpRequestStatus httpRequestStatus = في انتظار updateHero (معرف ، اسم محدث) ؛
  if (httpRequestStatus == HttpRequestStatus.DONE) {
    طباعة (httpRequestStatus.toString ())؛
    setState (() {
      
    })؛
  }
}

ما يلي هو رمز updateHero

التحديث المستقبلي Hero (int id ، اسم السلسلة)
  httpRequestStatus = HttpRequestStatus.NOT_DONE؛
  عنوان url النهائي = '$ _heroesUrl / $ id' ؛
  الرد النهائي = في انتظار http.put (url ،
      headers: _headers، body: json.encode ({'id': id، 'name': name}))؛
  إذا (response.statusCode == 200) {
    طباعة (response.body.toString ())؛
    httpRequestStatus = HttpRequestStatus.DONE؛
  } آخر {
    httpRequestStatus = HttpRequestStatus.ERROR؛
  }
}
دعنا نتبادل هوك مع ثور

كملخص ، قمنا بتغطية كيفية إنشاء تطبيق خادم الويب الخاص بنا الذي يقوم بتنفيذ تطبيق RESTful api وتمكنا من إنشاء تطبيق Flutter لأداء وظائف CRUD الأساسية مع PostgreSQL.

جيثب

https://github.com/tattwei46/flutter_crud_postgresql

إذا وجدت هذا المقال مفيدًا وتعليميًا ، فاعطيه بعضًا - لتشجعني على كتابة المزيد من هذا في المستقبل

The Flutter Pub هو منشور متوسط ​​يجلب لك أحدث الموارد المذهلة مثل المقالات ومقاطع الفيديو والرموز والبودكاست وما إلى ذلك عن هذه التكنولوجيا الرائعة لتعليمك كيفية إنشاء تطبيقات جميلة باستخدامها. يمكنك أن تجدنا على Facebook و Twitter و Medium أو معرفة المزيد عنا هنا. نحن نحب الاتصال! وإذا كنت كاتباً مهتمًا بالكتابة لنا ، فيمكنك القيام بذلك من خلال هذه الإرشادات.