Modèle BLoC avec un exemple simple

Et encore une fois sur BLoC en utilisant l'exemple de compteur Flutter classique.


En lisant quelques articles sur la programmation réactive et en utilisant le modèle BLoC dans les applications, j'ai réalisé que je ne rattrapais pas quelque chose. Comme d'habitude, il n'y a pas assez de temps pour tout, mais maintenant, il y avait une heure libre et il y a de la force - décidé, j'écrirai l'application Flutter la plus simple avec le modèle BLoC.


Sous applications chat animashka et explications pourquoi je l'ai écrit de cette façon. L'avis de la communauté est très intéressant.


image


Oui, nous avons déjà écrit à plusieurs reprises sur ce modèle, mais de toute façon, il n'y a pas d'instructions claires et de règles d'application pour cela, et la question se pose souvent de savoir comment implémenter correctement la logique dans l'application.


Le but de l'article est de clarifier un peu pour moi et, espérons-le, pour les lecteurs.


Ainsi, la définition du modèle, telle qu'elle a été exprimée par les ingénieurs de Google - BLOC est une classe simple dans laquelle:


  1. tous les flux de sortie
  2. toutes les entrées sont des flux
  3. cette classe doit supprimer la logique de l'interface visuelle

Pour implémenter ce modèle, nous pouvons, si nécessaire, utiliser la bibliothèque rxdart , mais nous ne pouvons pas l'utiliser.


Cela ne supprimera pas la réactivité comme vous pourriez le penser. Au fur et à mesure que les créateurs du package écrivent eux-mêmes, rxdart ajoute des fonctionnalités aux fonctionnalités riches déjà intégrées du langage Dart en travaillant avec les flux.


App



Donc, nous prenons l'application avec des compteurs, qui est créée automatiquement lorsque le projet est créé et essayons de le réécrire en utilisant le modèle BLoC.


Tâches:


  1. Supprimer toute logique des widgets
  2. Dans la classe BLoC, ne recevez que les flux d'entrée et sortez uniquement les flux de sortie. Par exemple, la fonction proposée dans les commentaires de l' article .

image


cela ne nous convient pas, car il viole la règle de ne transmettre que des flux à la classe.


Solution:


  1. Nous supprimons toute la logique des widgets. Nous créons la classe Stateless et arrêtons de mettre à jour l'état avec setState.
  2. Nous affichons les relevés de compteur à différents endroits à l'aide du widget intégré, spécialement conçu pour afficher les données des flux - 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, ), ), ), ); } } 

  1. Nous créons une classe distincte où nous implémentons le modèle BLoC:
    3.1 Toutes les propriétés et méthodes de classe sont masquées.
    3.2 Pour recevoir et transférer l'état, nous utilisons des flux qui sont visibles de l'extérieur à l'aide de getters (mais voici un article sympa à leur sujet ).

 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(); } } 

C'est tout, nous avons un exemple de travail dans lequel nous transmettons et recevons l'état par des flux et affichons des données dans les widgets nécessaires sans appliquer de logique dans la partie visuelle.


Ainsi, nous pouvons séparer tous les calculs, transferts de données, etc. depuis l'interface. Par exemple, si vous ajoutez différentes étiquettes au compteur en fonction de la quantité et que vous les prenez dans une base de données externe, alors toute cette logique passera déjà par BLoC - notre interface n'en saura rien.


Note 1: notez que nous créons une instance de la classe> CounterBloc counterBloc = CounterBloc (); puis nous en obtenons des données. Si nous avons besoin de ces données sur différents écrans (dans des classes espacées), nous pouvons alors utiliser des widgets hérités pour le transfert ou créer Singleton à partir de notre classe.


Exemple de code Github


Bon codage pour tout le monde!


Continuation


Dans la suite, nous transférons l'état sur différents écrans, enregistrons les données dans la mémoire permanente du téléphone, testons BLoC https://habr.com/en/post/485002/

Source: https://habr.com/ru/post/fr475404/


All Articles