【问题标题】:The argument type 'Stream<List<ObjectModel>>' can't be assigned to the parameter type 'List<ObjectModel>'参数类型“Stream<List<ObjectModel>>”不能分配给参数类型“List<ObjectModel>”
【发布时间】:2021-11-05 18:08:20
【问题描述】:

我正在使用 BLoC 模式(带有 rxdart 包)来读取“EmpresaDatosModel”列表,当尝试包含接收器时,它会抛出以下错误:

参数类型'Stream >'不能是 分配给参数类型'List '。

在 BLoC 模式中,我使用以下代码:

class EmpresaDatosBloc {

  final _empresaDatosController = new BehaviorSubject<List<EmpresaDatosModel>>();
  Stream <List<EmpresaDatosModel>>  get empresaDatosStream   => _empresaDatosController.stream;

  Stream<List<EmpresaDatosModel>> cargarEmpresasStream() {
    final empresasList = _empresaDatosProvider.cargarEmpresasStream();

    _empresaDatosController.sink.add(empresasList); //THE ERROR THROWS HERE

    return empresasList;
  }
  dispose() {
    _empresaDatosController?.close();
  }
}

从 Firebase RTDB 进行查询的提供程序具有以下内容:

  Stream<List<EmpresaDatosModel>> cargarEmpresasStream() {
    
    Query resp = db.child('admon');
    final empStream = resp.onValue;

    final publicarStream = empStream.map((event) {
      final empMap = Map<String, dynamic>.from(event.snapshot.value);
      final empList = empMap.entries.map((e) {
        return EmpresaDatosModel.fromJson(Map<String,dynamic>.from(e.value));
      }).toList();
      return empList;
    });
    return publicarStream;
  }

显示小部件如下所示:

    final empresaDatosBloc = Provider.empresaDatosBloc(context);
    empresaDatosBloc.cargarEmpresasStream();
    //---
    return StreamBuilder(
         stream: empresaDatosBloc.empresaDatosStream, 
         builder: (BuildContext context, snapshot){
                  final empresasList = [];
                  if (snapshot.hasData) {
                    final myList = snapshot.data as List<EmpresaDatosModel>;

                    myList.forEach((element) {
                      empresasList.add(element);
                    });
                  }

如何将List&lt;EmpresaDatosModel&gt; 分配给接收器以修复错误?

【问题讨论】:

    标签: flutter firebase-realtime-database bloc rxdart


    【解决方案1】:

    您可以拨打.addStream_empresaDatosControllerBehaviorSubject

    这会将数据和错误事件转发到控制器的流。

        _empresaDatosController.addStream(empresasList);
    

    【讨论】:

    • 谢谢@victoreonmosele。它工作正常。但是,当我切换到另一个屏幕并返回时出现错误:Bad state: You cannot add items while items are being added from addStream。我能修好吗?
    • 您是否在您拥有StreamBuilder 的小部件的 dispose 方法中处理该块?
    • 是的,我想是的。我正在使用dispose(){_empresaDatosController?.close();}
    • 明确地说,我在 BLoC 中使用 dispose。我有 Streambuilder 的地方是 StatelessWidget
    • 我将 SatelessWidget 转换为 StatefulWidget 以便处理 StreamBuilder 正在工作的 empresaDatosBloc,但出现相同的错误:Bad state: You cannot add items while items are being added from addStream
    【解决方案2】:

    希望能帮到你。 只需保留对StreamSubscription 的引用并使用Stream.listen() 方法

    
    class EmpresaDatosBloc {
      StreamSubscription<void>? _subscription;
    
      final _empresaDatosController = new BehaviorSubject<List<EmpresaDatosModel>>();
      Stream <List<EmpresaDatosModel>>  get empresaDatosStream   => _empresaDatosController.stream;
    
      void cargarEmpresasStream() {
        _subscription?.cancel();
        _subscription = _empresaDatosProvider.cargarEmpresasStream()
          .listen(_empresaDatosController.add, onError: _empresaDatosController.addError);
      }
      dispose() {
        _subscription?.cancel();
        _empresaDatosController?.close();
      }
    }
    

    【讨论】:

    • 完美运行!!您推荐使用 Streambuilder 在小部件中使用 Stateful 还是 Stateless?
    • IMO,应该是无状态的
    • 为什么? dispose函数不方便?
    • @DavidL 使用 Stateful 来包含和处理 bloc(是必需的)(例如 Screen/Page),否则尽可能使用 Stateless
    猜你喜欢
    • 2021-07-04
    • 2021-12-10
    • 2021-10-24
    • 2022-11-05
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    • 2021-11-06
    相关资源
    最近更新 更多