Umgang mit dem Status in Flutter mithilfe des BLoC-Musters

Letztes Jahr habe ich Flutter aufgenommen und ich muss sagen, dass es bisher eine großartige Reise war. Flutter ist Googles fantastisches Framework für die Erstellung hochwertiger Anwendungen für Android und iOS.

Wie beim Erstellen fast jeder Anwendung muss immer der Anwendungsstatus behandelt werden. Es ist wichtig, dass das staatliche Management effizient gehandhabt wird, um technische Schulden zu vermeiden, insbesondere wenn Ihre Anwendung wächst und komplexer wird.

In Flutter sind alle UI-Komponenten Widgets. Wenn Sie anfangen, diese Widgets zu erstellen, um Ihre fantastische App zu erstellen, erhalten Sie einen Baum tief verschachtelter Widgets. Diese Widgets müssen höchstwahrscheinlich den Anwendungsstatus miteinander teilen.

In diesem Artikel erfahren Sie, wie Sie den Status in Flutter mithilfe des BLoC-Musters behandeln.

Das staatliche Management in Flutter kann auf verschiedene Arten erreicht werden:

Geerbtes Widget : Mit dieser Option können Sie Daten an die untergeordneten Widgets weitergeben. Die Widgets werden neu erstellt, wenn sich der Status der App ändert. Der Nachteil der Verwendung der InheritedWidget-Basisklasse besteht darin, dass Ihr Status endgültig ist. Dies wirft ein Problem auf, wenn Sie Ihren Status ändern möchten.

Modell mit Gültigkeitsbereich : Dies ist ein externes Paket, das auf InheritedWidget basiert und eine etwas bessere Möglichkeit bietet, auf den Status zuzugreifen, ihn zu aktualisieren und ihn zu ändern. Sie können ein Datenmodell einfach von einem übergeordneten Widget an seine Nachkommen übergeben. Darüber hinaus werden alle untergeordneten Elemente neu erstellt, die das Modell verwenden, wenn das Modell aktualisiert wird.

Dies kann zu Leistungsproblemen führen, abhängig davon, wie viele ScopedModelDescendants ein Modell hat, da diese bei einem Update neu erstellt werden.

Dieses Problem kann behoben werden, indem das ScopedModel in mehrere Modelle zerlegt wird, sodass Sie feinkörnigere Abhängigkeiten erhalten. Das Setzen des rebuildOnChangeFlags, um falsedieses Problem ebenfalls zu beheben, bringt jedoch die kognitive Belastung mit sich, zu entscheiden, welches Widget neu erstellt werden soll oder nicht.

Redux : Ja! Wie bei React gibt es ein Redux-Paket, mit dem Sie auf einfache Weise einen Redux-Speicher in Flutter erstellen und nutzen können. Wie bei seinem JavaScript-Gegenstück gibt es normalerweise ein paar Zeilen Boilerplate-Code und den Roundtrip von Aktionen und Reduzierungen .

Geben Sie das BLoC-Muster ein

Das BLoC-Muster (Business Logic Component) ist ein Muster, das von Google erstellt und bei Google I / O '18 angekündigt wurde. Das BLoC-Muster verwendet die reaktive Programmierung, um den Datenfluss innerhalb einer App zu verarbeiten.

Ein BLoC steht als Vermittler zwischen einer Datenquelle in Ihrer App (z. B. einer API-Antwort) und Widgets, die die Daten benötigen. Es empfängt Ereignis- / Datenströme von der Quelle, verarbeitet alle erforderlichen Geschäftslogiken und veröffentlicht Datenänderungsströme an Widgets, die an ihnen interessiert sind.

Ein BLoC besteht aus zwei einfachen Komponenten: Sinks und Streams , die beide von einem StreamController bereitgestellt werden . Sie fügen Ströme Ereignis / Dateneingabe in ein Wasch- oder Spülbecken und hören , wie Ströme von Datenausgabe über einen ihnen Strom .

Auf einen StreamController kann über die ‘dart:async’Bibliothek oder als PublishSubject , ReplaySubject oder BehaviourSubject über das rxdartPaket zugegriffen werden .

Unten sehen Sie einen Code-Ausschnitt, der ein einfaches BLoC zeigt:

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

Ein BLoC ist eine einfache Dart-Klasse. Im obigen Code-Snippet haben wir eine CounterBlocKlasse erstellt und darin eine, StreamControllerdie wir aufgerufen haben counterController. Wir haben einen Getter für unseren Stream namens erstellt getCount, eine updateCountMethode, die beim Aufruf Daten in unsere Senke hinzufügt, und eine disposeMethode zum Schließen unseres StreamControllers.

Um auf die Daten in unserem Stream zuzugreifen, haben wir ein StreamBuilderWidget erstellt, unseren Stream an seine streamEigenschaft übergeben und auf die Daten in seiner builderFunktion zugegriffen .

BLoC implementieren

Wir werden die Standard-Flutter-Beispiel-App für die Verwendung eines BLoC konvertieren. Lassen Sie uns fortfahren und eine neue Flutter-App generieren. Führen Sie in Ihrem Terminal den folgenden Befehl aus:

$ flutter create bloc_counter && cd bloc_counter

Öffnen Sie die App in Ihrem bevorzugten Editor und erstellen Sie drei Dateien im Ordner lib: counter.dart, counter_provider.dartund counter_bloc.dart.

Unser CounterProviderTestament enthält eine Ganzzahl und eine Methode, um sie zu erhöhen. Fügen Sie der counter_provider.dartDatei den folgenden Code hinzu :

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

Als nächstes implementieren wir unseren Zähler BLoC. Fügen Sie den folgenden Code in Ihre counter_block.dartDatei ein:

In unserer CounterBlocKlasse haben wir einen Teil unseres obigen Beispielcodes verwendet. In Zeile 7 haben wir unsere CounterProviderKlasse instanziiert und in der updateCountMethode die Provider-Methode aufgerufen, um die Anzahl zu erhöhen. In Zeile 13 haben wir die Anzahl an unsere Spüle übergeben.

Ersetzen Sie den Code in Ihrer main.dartDatei durch den folgenden Code. Im folgenden Code haben wir einfach den größten Teil des Standardzählercodes entfernt, den wir in unsere counter.dartDatei verschieben. Immer wenn die incrementCounterMethode aufgerufen wird, rufen wir die BLoC- updateCountMethode auf, die die Anzahl aktualisiert und zu unserer Senke hinzufügt.

Jetzt empfängt und streamt unser BLoC Daten. Wir können auf diese Daten zugreifen und sie über einen StreamBuilder auf einem Bildschirm anzeigen . Wir verpacken jedes Widget, das die Daten benötigt, in ein StreamBuilder-Widget und übergeben den Stream mit den Daten an dieses. Fügen Sie der counter.dartDatei den folgenden Code hinzu :

Im obigen Code haben wir ein Stateful-Widget. In unserer Statusklasse rufen wir in Zeile 13 die Dispose-Methode unseres Blocks auf, sodass der Stream-Controller geschlossen werden kann, wenn das Widget aus dem Baum entfernt wird.

In Zeile 19 geben wir ein StreamBuilder-Widget zurück und in Zeile 20 übergeben wir den Getter für unseren Stream an ihn und auch die Anfangsdaten in Zeile 21. Der StreamBuilder verfügt auch über eine, mit builderder wir über a auf die Daten zugreifen können snapshot. In Zeile 30 greifen wir auf die Daten im Snapshot zu und zeigen sie an.

Führen Sie die App aus, indem Sie den folgenden Befehl ausführen. Stellen Sie sicher, dass ein Emulator ausgeführt wird.

$ flutter run

Klicken Sie bei laufender App auf das Plus-Symbol und beobachten Sie, wie sich der Zähler mit jedem Klick erhöht.

Gemeinsam konnten wir die einfachste Form eines BLoC in Flutter implementieren. Das Konzept bleibt unabhängig von Ihrem Anwendungsfall gleich.

Ich hoffe, Sie fanden diesen Artikel hilfreich. Bitte tun und teilen, damit andere diesen Artikel finden können. Schlagen Sie mich auf Twitter @developia_ mit Fragen oder für einen Chat.