【问题标题】:How to combine multi data steams in one BLOC?如何将多个数据流合并到一个 BLOCK 中?
【发布时间】:2019-02-14 19:32:33
【问题描述】:

我有一个小部件来表示按最接近用户当前位置排序的商店列表,也应该应用过滤。

数据在:

  1. 存储来自 Firestore 集合流的数据
  2. geolacator 中的当前用户位置。
  3. 从共享首选项中筛选选项 (可以随时更改)
  4. 用户选择的列表排序方式

数据输出:过滤、排序、商店列表。

在这种情况下什么模式是最佳实践?

【问题讨论】:

    标签: dart stream flutter


    【解决方案1】:

    rxdart : https://pub.dartlang.org/packages/rxdart 如果你想将数据组合在一起,你可以使用

    var myObservable = Observable.combineLatest3(
    myFirstStream, 
    mySecondStream, 
    myThirdStream, 
    (firstData, secondData, thirdData) => print("$firstData $secondData $thirdData"));    
    
    
    you can combine from ( combineLatest2, combineLatest... combineLatest9 )
    

    或 结合最新流 像这个例子

         CombineLatestStream.list<String>([
            Stream.fromIterable(["a"]),
            Stream.fromIterable(["b"]),
            Stream.fromIterable(["C", "D"])])
            .listen(print);
    

    【讨论】:

      【解决方案2】:

      数字 2、3 和 4 是您将通过接收器发送到该集团的输入。该集团监听这些接收器并相应地更新 Firestore 查询。仅此一项就足以让 Firestore 将适当的快照发送到小部件正在侦听的输出流。

      如果您无法直接使用 Firestore 的 API 进行排序或过滤,您可以使用 stream.map 或在其上应用 StreamTransformer。转换器通过实现其bind 方法,为您提供了很大的灵活性来侦听流并动态更改或忽略事件。

      所以你可以这样做:

      Stream<Store> get stores => _firestoreStream
        .transform(filter)
        .transform(sort);
      

      查看this page 了解 dart 中的一般流,查看rxdart 了解更复杂的流操作。

      【讨论】:

        【解决方案3】:

        根据个人经验,我发现一个块有多个输入会导致难以测试代码。块内隐含的并发问题会导致令人困惑的场景。

        我在Adding testing to a Flutter app 帖子中构建它的方式是创建单个输入流,但在消息中添加标记,指出消息属于哪个数据流。它使测试变得理智。

        【讨论】:

          【解决方案4】:

          在这种情况下,我认为有多个异步处理。这个实现可能很复杂。并且存在竞争条件的可能性。

          我会如下实现。

          1. 从 Firestore 和 Bloc 中用户可见的 ViewModel 中分离模型流。小部件仅监听 ViewModel。(例如,使用 StreamBuilder)
          2. 仅在 Bloc 中限制业务逻辑处理。首先,将使用 SharedPreferences 的处理转移到 Bloc 中。
          3. 为用户输入创建 UserControl 类。
          4. 分支处理取决于扩展 UserControl 的用户输入类型

          希望对你有帮助。

          例如:

          import 'dart:async';
          import 'package:rxdart/rxdart.dart';
          
          class ViewModel {}
          
          class DataFromFirestoreModel {}
          
          abstract class UserControl {}
          
          class UserRequest extends UserControl {}
          
          class UserFilter extends UserControl {
            final String keyWord;
          
            UserFilter(this.keyWord);
          }
          
          enum SortType { ascending, descending }
          
          class UserSort extends UserControl {
            final SortType sortType;
          
            UserSort(this.sortType);
          }
          
          class Bloc {
            final controller = StreamController<UserControl>();
            final viewModel = BehaviorSubject<ViewModel>();
          
            final collection = StreamController<DataFromFirestoreModel>();
          
            Bloc() {
              controller.stream.listen(_handleControl);
            }
          
            _handleControl(UserControl control) {
              if (control is UserRequest) {
                _handleRequest();
              } else if (control is UserFilter) {
                handleFilter(control.keyWord);
              } else if (control is UserSort) {
                handleSort(control.sortType);
              }
            }
          
            _handleRequest() {
              //get location
              //get data from sharedPreferences
              //get data from firestore
          
              ViewModel modifiedViewModel; // input modifiedViewModel
              viewModel.add(modifiedViewModel);
            }
          
            handleSort(SortType sortType) {
              final oldViewModel = viewModel.value;
              //sorting oldViewModel
          
              ViewModel newViewModel; // input sorted oldViewModel
              viewModel.add(newViewModel);
            }
          
            handleFilter(String keyWord) {
              //store data to sharedPreferences
              //get data from Firestore
          
              ViewModel modifiedViewModel; // input modifiedViewModel
              viewModel.add(modifiedViewModel);
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2019-04-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-02-02
            • 2019-05-27
            • 2010-10-06
            • 1970-01-01
            • 2023-03-18
            相关资源
            最近更新 更多