ومرة أخرى حول BLoC باستخدام مثال العداد Flutter الكلاسيكي.
عند قراءة بعض المقالات حول البرمجة التفاعلية واستخدام نمط BLoC في التطبيقات ، أدركت أنني لم ألحق بشيء ما. كالعادة ، لا يوجد ما يكفي من الوقت لكل شيء ، ولكن الآن ، كانت هناك ساعة مجانية وهناك قوة - قررت ، سأكتب أبسط تطبيق Flutter مع نمط BLoC.
تحت تطبيقات animashka القط وشروحات لماذا كتبت عليه بهذه الطريقة. مثيرة جدا للاهتمام هو رأي المجتمع.

نعم ، لقد كتبنا بالفعل عن هذا النمط عدة مرات ، ولكن على أي حال ، لا توجد تعليمات واضحة وقواعد التطبيق لذلك ، وغالباً ما يطرح السؤال حول كيفية تنفيذ المنطق في التطبيق بشكل صحيح.
الغرض من هذا المقال هو إضفاء بعض الوضوح على نفسي ، وآمل ، للقراء.
لذلك ، فإن تعريف النموذج ، كما عبر عنه مهندسو Google - BLOC عبارة عن فئة بسيطة:
- جميع المخرجات تيارات
- جميع المدخلات تيارات
- يجب على هذه الفئة إزالة المنطق من الواجهة البصرية
لتنفيذ هذا النمط ، يمكننا ، إذا لزم الأمر ، استخدام مكتبة rxdart ، لكننا قد لا نستخدمها.
هذا لن يزيل التفاعل كما تعتقد. بينما يكتب منشئو الحزمة أنفسهم ، يضيف rxdart وظائف إلى الميزات الغنية المضمنة بالفعل في لغة Dart في العمل مع التدفقات.
تطبيق

لذلك ، نأخذ التطبيق مع عدادات ، والتي يتم إنشاؤها تلقائيًا عند إنشاء المشروع ومحاولة إعادة كتابته باستخدام نموذج BLoC.
الأهداف:
- إزالة كل المنطق من الحاجيات
- في فئة BLoC ، يمكنك تلقي تدفقات الإدخال فقط وإخراج تدفقات الإخراج فقط. على سبيل المثال ، الوظيفة المقترحة في التعليقات على المقال .

هذا لا يناسبنا ، لأنه ينتهك قاعدة نقل التدفقات فقط إلى الفصل.
الحل:
- نزيل كل المنطق من الحاجيات. نجعل فئة عديمي الجنسية ونتوقف عن تحديث الحالة مع setState.
- نعرض قراءات العدادات في أماكن مختلفة باستخدام الأداة المدمجة ، والتي تم تصميمها خصيصًا لعرض البيانات من التدفقات - StreamBuilder.
class MyHomePage extends StatelessWidget { CounterBloc counterBloc = CounterBloc(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: StreamBuilder<int>( stream: counterBloc.pressedCount, builder: (context, snapshot) { return Text( 'Flutter Counter Bloc Example - ${snapshot.data.toString()}', ); }), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), StreamBuilder<int>( stream: counterBloc.pressedCount, builder: (context, snapshot) { return Text( '${snapshot.data.toString()}', style: Theme.of(context).textTheme.display1, ); }), ], ), ), floatingActionButton: Container( width: 100.0, height: 100.0, child: FloatingActionButton( onPressed: () { counterBloc.incrementCounter.add(null); }, tooltip: 'Increment', child: Text( "+ \n send \n to BLoC", textAlign: TextAlign.center, ), ), ), ); } }
- نخلق فئة منفصلة حيث نطبق نموذج BLoC:
3.1 جميع خصائص الفصل وطرقه مخفية.
3.2 لتلقي حالة النقل ونقلها ، نستخدم التدفقات المرئية من الخارج باستخدام الحروف (ولكن هذه مقالة رائعة عنها ).
class CounterBloc { int _counter; CounterBloc() { _counter = 1; _actionController.stream.listen(_increaseStream); } final _counterStream = BehaviorSubject<int>.seeded(1); Stream get pressedCount => _counterStream.stream; Sink get _addValue => _counterStream.sink; StreamController _actionController = StreamController(); StreamSink get incrementCounter => _actionController.sink; void _increaseStream(data) { _counter += 1; _addValue.add(_counter); } void dispose() { _counterStream.close(); _actionController.close(); } }
هذا كل شيء ، لدينا مثال عملي نقوم فيه بنقل واستقبال الحالة عن طريق التدفقات وعرض البيانات في الأدوات المصغّرة الضرورية دون تطبيق أي منطق في الجزء المرئي.
وبالتالي ، يمكننا فصل جميع الحسابات ، ونقل البيانات ، وما إلى ذلك. من الواجهة. على سبيل المثال ، إذا أضفت تسميات مختلفة إلى العداد اعتمادًا على الكمية وأخذتها من قاعدة بيانات خارجية ، فسوف يمر كل هذا المنطق بالفعل عبر BLoC - لن تعرف واجهتنا أي شيء عن ذلك.
ملاحظة 1: لاحظ أننا نقوم بإنشاء مثيل للفئة> CounterBloc counterBloc = CounterBloc ()؛ ثم نحصل على بيانات منه. إذا كنا بحاجة إلى هذه البيانات على شاشات مختلفة (في فئات متباعدة) ، فيمكننا إما استخدام الأدوات المصغرة الموروثة للنقل أو إنشاء Singleton من صفنا.
جيثب رمز المثال
الترميز الجيد للجميع!
تمديد
في تتمة ، نقوم بنقل الحالة على شاشات مختلفة ، وحفظ البيانات في الذاكرة الدائمة للهاتف ، واختبار BLoC https://habr.com/en/post/485002/