AWS増幅データストアによるフラッタブロックパターンの使用



導入
昨年、私は本当にAWSがベータ版をリリースしたので、フラッタ開発を調べ始めましたAWS Amplify Flutter client libraries . これらAmplify Flutter libraries are now GA
そして、私はAWS AmplifyのDatastoreカテゴリーのオフライン同期機能を示すアプリケーションを構築し始めました.
私はデータストアを使用して様々なUIを構築したので、私はすぐに状態を処理する方法の古い問題に移動し、状態を変更すると、消費イベントを消費します.ここが私が出くわしたところですBLoC パターンとその簡略兄弟化Cubit . だから私はそれについての迅速なポストを書くと思う私はそのシンプルさと優雅さをAWS増幅のデータストアの呼び出しを包むのが好きだった.
このポストでは、私はブロックパターンの例を通してあなたを歩きます.そして、どのようにAWS Amplify Datastore API呼び出しのあなたの使用を改善するためにそれを使うことができますか?

抽象データアクセス
知らない人にAmplify DataStore , これは、オフラインとオンラインのシナリオのための追加コードを記述せずに共有と分散データをレバレッジのためのプログラミングモデルを提供しています.我々がこれを沸騰させるならば、単にデータストアAPI呼び出しの一つのセットで働くことはデータがローカルで持続されるだけでなく、接続された雲バックエンドで同期されるだけであることを意味します.
データストアAPI呼び出しは、どんな伝統的なデータ永続化メカニズムのようにもrepository pattern - 私はこれらの呼び出しをリポジトリ内でラップしているので、アプリケーションロジックからそれらを抽象化し、テスト可能にします.

理解する
最初の状態の簡単な概要を持って、特にフラッターのブロックパターンの使用.パターン自体は非常に反応性のスタイルであり、ビジネスロジックコンポーネントを表します.ブロックの要点は、アプリケーション内のすべてのイベントのストリームとして表される必要があります:ウィジェットのイベントを提出;他のウィジェットが応答します.ブロックは、中間に座って、会話を管理します.追加の利点は、DARTは、言語に焼かれているストリームで動作するための構文が付属しています.典型的なプログラムがどのようにBLOCと倉庫パターンをUI層で使用するかを見ることができます

見ることができるように、データは、BLOC層を通してUI層から倉庫に流れ込みます.この例では、Amplify.DataStore.save() コール.

キュービット理解
説明したように、ブロックはイベントの流れを使用します、そして、その自然の形で、それからそれからUI装置へのワイヤーは簡単でありません.ウィジェットによって生成されたイベントをリッスンしてアクションを取るには、アプリケーションでBLOCを実装する簡単な方法であるCubitを使用できます.BLOCとCubitの主な違いは、Cubitは単純な状態管理に適しています.そこでは、状態にバインドするイベントが1つだけあります.ブロックは、州にマップするために多くのイベントを持つことができる複雑な状態管理のためです.これは、データストア呼び出しを増幅するマイリポジトリと相互作用するときに使用してきたものです.私はよく物事を簡単に進む方法を見つける.

簡単な例をまとめる
それで、私がこれを立証するために、私はCubitを使っている単純な「更新」アクションを実行するのに必要な手順を通してあなたを歩かせます.まず最初に必要なのは、Pubspecで必要な依存関係をインストールすることです.気象研

ここでは、AWAYを実行する必要がある依存関係を見ることができます.いったんプルダウンしたら、データストアAPI呼び出しをラップするためにリポジトリクラスを作成します.
import 'package:amplify_flutter/amplify.dart';
import 'package:flutter_droidcon/models/ShoppingListItem.dart';

class ShoppingListItemRepository {
  Future<List<ShoppingListItem>> getListItems() async {
    List<ShoppingListItem> items = new List.empty();
    try {
      items = await Amplify.DataStore.query(ShoppingListItem.classType);
    } catch (e) {
      print("Could not query DataStore: ");
    }
    return items;
  }

  Future<void> createListItems(String itemName) async {
    final item = ShoppingListItem(itemName: itemName, isComplete: false);
    try {
      await Amplify.DataStore.save(item);
    } catch (e) {
      throw e;
    }
  }

  Future<void> updateListItem(ShoppingListItem item, bool isComplete) async {
    final updatedItem = item.copyWith(isComplete: isComplete);
    try {
      await Amplify.DataStore.save(updatedItem);
    } catch (e) {
      throw e;
    }
  }

  Stream observeTodos() {
    return Amplify.DataStore.observe(ShoppingListItem.classType);
  }
}

このコードには多くのデータ操作がありますget/create/update それはARGSで通過されて、それからAmplify Datastore API呼び出しを構築するのに用いられます.
次の段階はこれらの呼び出しをラップするキュービットを作成することです.上記のリポジトリクラスのキュービットは次のようになります.
class ShoppingListItemCubit extends Cubit<ShoppingListState> {
  final _shoppingListRepo = ShoppingListItemRepository();

  ShoppingListItemCubit() : super(LoadingShoppingList());

  void getListItems() async {
    if (state is ShoppingListSuccess == false) {
      emit(LoadingShoppingList());
    }

    try {
      final items = await _shoppingListRepo.getListItems();
      emit(ShoppingListSuccess(listItems: items));
    } catch (e) {}
  }

  void createListItems(String itemName) async {
    await _shoppingListRepo.createListItems(itemName);
  }

  void updateListItem(ShoppingListItem item, bool isComplete) async {
    await _shoppingListRepo.updateListItem(item, isComplete);
  }

  void observeItems() {
    final itemStream = _shoppingListRepo.observeTodos();
    itemStream.listen((_) => getListItems());
  }
}
このクラスのメソッドのいくつかの中にもemit() 状態変化最後に、上記で定義されたキュービットの使い方を見てみましょう.使用updateListItem 例として、UIウィジェット内でどのように見えるかを示します.
Widget _shoppingItemListView(List<ShoppingListItem> items) {
    return ListView.builder(
      itemCount: items.length,
      itemBuilder: (context, index) {
        final item = items[index];
        return Card(
          child: CheckboxListTile(
              title: Text(item.itemName),
              value: item.isComplete,
              onChanged: (newValue) {
                BlocProvider.of<ShoppingListItemCubit>(context)
                    .updateListItem(item, newValue!);
              }),
        );
      },
    );
  }
ウィジェット内のパターンの実装を見ることができますonChanged プロパティは些細なものであり、我々はBloseProviderを必要とするオブジェクトの型を調べるだけで、値をblobクラスのメソッドに送信します.非常にシンプルだが非常に効果的.

総括
あなたが見ることができるように、フラッタと増幅を使用してビルドは本当にあなたのソリューションにベストプラクティスのアプリケーションアーキテクチャでベーキングに自分自身を貸す.この記事では、リポジトリとブロックパターンの使用方法と、それらをどうやって増幅するDatastore API呼び出しをファサードできるかを示しました.次に、これは非常に簡単にコードをオンラインでオフラインモードで機能するアプリケーションのデータ永続化メカニズムを構築することができます.
複数のリポジトリとキューを使用して、より複雑な例を見たいなら、これは非常に短い例でしたMy Github Repo . 私はまた、アプリケーションを構築する方法を詳述した記事を書いている.
いつものように、フィードバックを提供することによって、将来の記事を手伝ってください.
次まで.