Kako se obrađuje stanje u Flutteru pomoću BLoC uzorka

Prošle sam godine pokupila Fluttera i moram reći da je to do sada bilo strašno putovanje. Flutter je Googleov sjajni okvir za izradu visokokvalitetnih aplikacija za Android i iOS.

Kao i kod izgradnje gotovo svake aplikacije, uvijek postoji potreba za rukovanjem stanjem aplikacije. Važno je da se državnim upravljanjem rukuje učinkovito kako bi se izbjeglo nagomilavanje tehničkog duga, pogotovo kako vaša aplikacija raste i postaje složenija.

U Flutteru su sve komponente korisničkog sučelja dodaci. Kad započnete sastavljati ove widgete kako biste stvorili svoju sjajnu aplikaciju, na kraju ćete dobiti stablo duboko ugniježđenih widgeta. Ovi će widgeti najvjerojatnije trebati međusobno dijeliti stanje aplikacije.

U ovom ćemo članku vidjeti kako se obrađuje stanje u Flutteru pomoću BLoC uzorka.

Državno upravljanje u Flutteru može se postići na nekoliko različitih načina:

Naslijeđeni widget : Omogućuje vam širenje podataka na njegove podređene widgete i widgeti se obnavljaju kad god se promijeni stanje aplikacije. Loša strana upotrebe osnovne klase InheritedWidget je ta što je vaše stanje konačno i to stvara problem ako želite mutirati svoje stanje.

Model s opsegom : Ovo je vanjski paket izgrađen na vrhu naslijeđenog widgeta i nudi malo bolji način za pristup, ažuriranje i mutiranje stanja. Omogućuje vam lako prenošenje podatkovnog modela s roditeljskog widgeta na njegovo potomstvo. Uz to, također obnavlja svu djecu koja koriste model kada se model ažurira.

To bi moglo pokrenuti problem s performansama, ovisno o tome koliko ScopedModelDescendants ima model, jer se obnavljaju kada postoji ažuriranje.

Ovaj se problem može riješiti raščlanjivanjem ScopedModel-a na više modela tako da se dobiju preciznije ovisnosti. Postavljanjem rebuildOnChangezastave falsetako toer rješava ovaj problem, ali sa sobom donosi kognitivno opterećenje odluke o tome koji widget treba obnoviti ili ne.

Redux : Da! Kao i kod React-a, postoji Redux paket koji vam pomaže da lako stvorite i konzumirate Redux trgovinu u Flutteru. Kao i njegov JavaScript kolega, obično postoji nekoliko redaka standardnog koda i kružno djelovanje i reduktori .

Unesite BLoC uzorak

Uzorak komponente poslovne logike (BLoC) obrazac je koji je stvorio Google i najavio ga na Google I / O '18. Uzorak BLoC koristi reaktivno programiranje za upravljanje protokom podataka unutar aplikacije.

BLoC predstavlja posrednika između izvora podataka u vašoj aplikaciji (npr. API odgovor) i widgeta koji trebaju podatke. Prima tokove događaja / podataka iz izvora, obrađuje svu potrebnu poslovnu logiku i objavljuje tijekove promjena podataka u widgetima koji su za njih zainteresirani.

BLoC ima dvije jednostavne komponente: Sudopere i potoke , a obje pruža StreamController . Dodajete tokove događaja / podataka koji se unose u Sudoper i slušate ih kao tokove podataka koji se izlažu kroz Stream .

StreamController može pristupiti preko ‘dart:async’knjižnice ili kao PublishSubject , ReplaySubject ili BehaviourSubject preko rxdartpaketa.

Ispod je isječak koda koji prikazuje jednostavni BLoC:

import 'dart:async'; // import 'package:rxdart/rxdart.dart'; if you want to make use of PublishSubject, ReplaySubject or BehaviourSubject. // make sure you have rxdart: as a dependency in your pubspec.yaml file to use the above import class CounterBloc { final counterController = StreamController(); // create a StreamController or // final counterController = PublishSubject() or any other rxdart option; Stream get getCount => counterController.stream; // create a getter for our Stream // the rxdart stream controllers returns an Observable instead of a Stream void updateCount() { counterController.sink.add(data); // add whatever data we want into the Sink } void dispose() { counterController.close(); // close our StreamController to avoid memory leak } } final bloc = CounterBloc(); // create an instance of the counter bloc //======= end of CounterBloc file //======= somewhere else in our app import 'counter_bloc.dart'; // import the counter bloc file here @override void dispose() { bloc.dispose(); // call the dispose method to close our StreamController super.dispose(); } ... @override Widget build(BuildContext context) { return StreamBuilder( // Wrap our widget with a StreamBuilder stream: bloc.getCount, // pass our Stream getter here initialData: 0, // provide an initial data builder: (context, snapshot) => Text('${snapshot.data}'), // access the data in our Stream here ); } ...

BLoC je jednostavna Dart klasa. U isječku koda gore stvorili smo CounterBlocklasu i u njoj, StreamControllerkoju smo nazvali counterController. Izradili smo getter za naš Stream pozvan getCount, updateCountmetodu koja dodaje podatke u naš Sink kada je pozvan i disposemetodu za zatvaranje našeg StreamControllera.

Da bismo pristupili podacima u našem streamu, stvorili smo StreamBuilderwidget i proslijedili naš stream u svoje streamvlasništvo i pristupili podacima u svojoj builderfunkciji.

Implementacija BLoC-a

Pretvorit ćemo zadanu aplikaciju Flutter za primjenu u BLoC. Idemo naprijed i generirajte novu aplikaciju Flutter. U vašem terminalu pokrenite sljedeću naredbu:

$ flutter create bloc_counter && cd bloc_counter

Otvorite aplikaciju u svoj omiljeni editor i stvoriti tri datoteke u mapi lib: counter.dart, counter_provider.darti counter_bloc.dart.

Naši CounterProviderće sadržati cijelu brojku i metodu za njezino povećanje. U counter_provider.dartdatoteku dodajte sljedeći kod :

class CounterProvider { int count = 0; void increaseCount() => count++; }

Dalje ćemo implementirati naš brojač BLoC. Dodajte donji kod u svoju counter_block.dartdatoteku:

U našoj CounterBlocklasi koristili smo dio gore navedenog početnog uzorka koda. U retku 7 napravili smo instancu naše CounterProviderklase, a u updateCountmetodi smo pozvali metodu dobavljača da poveća broj, a zatim smo u retku 13 prenijeli brojanje u naš Sink.

Zamijenite kod u main.dartdatoteci s kodom u nastavku. U donjem kodu jednostavno smo uklonili većinu zadanog broja brojača koji ćemo premjestiti u našu counter.dartdatoteku. Kad god se incrementCountermetoda pozove, zovemo BLoC-ovu updateCountmetodu koja ažurira brojanje i dodaje ga u naš Sudoper.

Sada naš BLoC prima i struji podatke. Tim podacima možemo pristupiti i prikazati ih na zaslonu putem programa StreamBuilder . Bilo koji dodatak koji treba podatke umotavamo u widget StreamBuilder i prosljeđujemo mu tok koji sadrži podatke. U counter.dartdatoteku dodajte sljedeći kod :

U gornjem kodu imamo widget s statusom. U našoj klasi stanja, u retku 13, nazivamo metodu raspolaganja bloka, tako da se kontroler toka može zatvoriti kad god se widget ukloni sa stabla.

On line 19, we return a StreamBuilder widget and line 20, we pass the getter for our stream to it and also an initial data on line 21. The StreamBuilder also has a builder which gives us access to the data via a snapshot. On line 30, we access and display the data in the snapshot.

Go ahead and run the app by running the command below. Ensure you have an emulator running.

$ flutter run

With your app running, click the plus icon and watch the counter increase with every click.

Together, we’ve been able to implement the simplest form of a BLoC in Flutter. The concept remains the same regardless of your use case.

I hope you found this article useful. Please do and share so others can find this article. Hit me up on Twitter @developia_ with questions or for a chat.