Flutter   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了architecture – Flutter嵌套的StreamBuilders导致Bad状态:Stream已被监听大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用视频 Flutter / AngularDart – Code sharing,better together (DartConf 2018)中描述的BLoC模式构建Flutter应用程序

BLoC基本上是一个带有Sink输入和Stream输出的视图模型.在我的例子中它看起来有点像这样:

class BLoC {
    // inputs
    Sink<String> inputTextChanges;
    Sink<Null> submitButtonClicks;

    // outputs
    Stream<bool> showLoading;
    Stream<bool> submitEnabled;
 }

我在层次结构根目录附近的小部件中定义了BLoC,并将其传递给它下面的小部件,包括嵌套的StreamBuilders.像这样:

architecture – Flutter嵌套的StreamBuilders导致Bad状态:Stream已被监听

顶级StreamBuilder监听BLoC上的showLoading流,以便它可以重建以显示重叠的进度微调器.底部StreamBuilder侦听submitEnabled流以启用/禁用按钮.

问题是每当showLoading流导致顶级StreamBuilder重建窗口小部件时,它也会重建嵌套窗口小部件.这本身就很好并且预期.但是,这会导致重新创建底部的StreamBuilder.当发生这种情况时,它会尝试重新订阅BLoC上的现有submitEnabled流,从而导致Bad状态:Stream已被监听

有没有办法在不创建所有输出BroadcastStream的情况下完成此操作?

(我也有可能从根本上误解BLoC模式.)

下面的实际代码例:

import 'package:Flutter/material.dart';
import 'package:rxdart/rxdart.dart';
import 'dart:async';

void main() => runApp(BlocExampleApp());

class BlocExampleApp extends StatefulWidget {

  BlocExampleApp({Key key}) : super(key: key);

  @override
  _BlocExampleAppState createState() => _BlocExampleAppState();
}

class _BlocExampleAppState extends State<BlocExampleApp> {

  Bloc bloc = Bloc();

  @override
  Widget build(BuildContext context) =>
      MaterialApp(
        home: Scaffold(
            appBar: AppBar(elevation: 0.0),body: new StreamBuilder<bool>(
                stream: bloc.showLoading,builder: (context,snapshot) =>
                snapshot.data
                    ? _overlayLoadingWidget(_buildContent(context))
                    : _buildContent(context)
            )
        ),);

  Widget _buildContent(context) =>
      column(
          crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[
            TextField(
              onChanged: bloc.inputTextChanges.add,),StreamBuilder<bool>(
                stream: bloc.submitEnabled,builder: ((context,snapshot) =>
                    MaterialButton(
                      onPressed: snapshot.data ? () => bloc.submitClicks.add(null) : null,child: Text('Submit'),)
                )
            )
          ]
      );

  Widget _overlayLoadingWidget(Widget content) =>
      Stack(
        children: <Widget>[
          content,Container(
            color: Colors.black54,Center(child: CircularProgressInDicator()),],);
}

class Bloc {
  final StreamController<String> _inputTextChanges = StreamController<String>();
  final StreamController<Null> _submitClicks = StreamController();

  // Inputs
  Sink<String> get inputTextChanges => _inputTextChanges.sink;

  Sink<Null> get submitClicks => _submitClicks.sink;

  // Outputs
  Stream<bool> get submitEnabled =>
      Observable<String>(_inputTextChanges.stream)
          .disTinct()
          .map(_isInputValid);

  Stream<bool> get showLoading => _submitClicks.stream.map((_) => truE);

  bool _isInputValid(String input) => true;

  void dispose() {
    _inputTextChanges.close();
    _submitClicks.close();
  }
}

解决方法

据我了解BLoC,您应该只有一个输出流连接到StreamBuilder.此输出流发出包含所有必需状态的模型.

你可以在这里看到它是如何完成的:https://github.com/ReactiveX/rxdart/blob/master/example/flutter/github_search/lib/github_search_widget.dart

如果需要组合多个流来生成模型(sowLoading和submitEnabled),则可以使用RxDart中的Observable.combineLatest将多个流合并为一个流.我使用这种方法,它的工作非常好.

大佬总结

以上是大佬教程为你收集整理的architecture – Flutter嵌套的StreamBuilders导致Bad状态:Stream已被监听全部内容,希望文章能够帮你解决architecture – Flutter嵌套的StreamBuilders导致Bad状态:Stream已被监听所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。