【问题标题】:How do you do Rx.CombineLatestStream using the flutter_bloc package你如何使用flutter_bloc包做Rx.CombineLatestStream
【发布时间】:2021-03-26 11:15:57
【问题描述】:

我整理了一个示例应用程序,该应用程序使用流实现了用户名和密码字段,并使用验证转换进行了验证。我为此使用了 RxDart,并连接了“登录”按钮以根据 2 个流结果为真启用/禁用。

bloc.dart

  Stream<bool> get submitValidWithCombineLatestStream =>
  CombineLatestStream([email, password], (list) => true);

login_page.dart

 Widget submitButton(Bloc bloc) {
 return StreamBuilder(
   stream: bloc.submitValidWithCombineLatestStream,
   builder: (_, snapshot) {
    return RaisedButton(
      color: Colors.deepPurpleAccent,
      child: Text(
        'Submit',
        style: TextStyle(color: Colors.white),
      ),
      onPressed: !snapshot.hasData ? null : bloc.submit,
    );
  },
 );
}

我已经使用 flutter_bloc 编写了相同的示例应用程序,但我试图弄清楚如何使用组合最新流的任何 bloc 启用/禁用“登录”按钮。有人知道怎么做吗?

我意识到这完全是矫枉过正,但我​​正在尝试使用这个简单的示例来解决这个问题,我不确定一旦转换为 bloc (flutter_bloc) 后如何访问所有很酷的 RxDart 功能。我希望在不导入/使用 RxDart 的情况下两全其美。

这可能吗?

我正在寻找的一个例子是:

  • 我正在构建一个需要 3 个不同后端调用的表单。我宁愿在所有 3 个调用都在工作时显示进度指示器,并阻止直到所有 3 个调用返回。我想通过 CombineLatestStreams 做到这一点,因为所有 3 个都返回 Steam Futures。

【问题讨论】:

    标签: flutter bloc flutter-bloc rxdart


    【解决方案1】:

    您的主要 bloc 类中的问题,请查看此 github 代码, https://github.com/hoc081098/flutter_validation_login_form_BLoC_pattern_RxDart

    简而言之,你可以使用 CombineLatestStream 你可以在你的主要集团类中设置 像这样,

    return LoginBloc._(
          emailChanged: emailS.add,
          passwordChanged: passwordS.add,
          submitLogin: () => submitLoginS.add(null),
          emailError$: emailError$,
          passwordError$: passwordError$,
          isLoading$: isLoadingS.stream,
          message$: message$,
          dispose: DisposeBag([...subjects, message$.connect()]).dispose,
        ); 
    

    【讨论】:

    • 我能够看到使用 RxDart 成功编写了解决方案。我想做的是使用 flutter_bloc 包解决问题。我确信有办法做到这一点,但我一直无法弄清楚。在我和我的团队提交之前,我们需要知道 bloc 包是否可以执行更复杂的操作。
    • 您没有添加足够的代码来理解错误,这就是为什么我向您提供与您的功能相同的代码,
    【解决方案2】:

    这就是使用 RxDart 将流与 bloc 组合的方式,如果侦听器中有新内容,您就会发出新值,仅此而已。 每当您想调用后端时,您都可以创建侦听器。

    import 'dart:async';
    import 'package:flutter_bloc/flutter_bloc.dart';
    import 'package:rxdart/rxdart.dart';
    
    class TestState {
      final bool isValid;
    
      TestState(this.isValid);
    }
    
    class TestCubit extends Cubit<TestState> {
      final List<StreamSubscription> _ss = [];
      final _emailSubject = BehaviorSubject<String>.seeded(null);
      final _passwordSubject = BehaviorSubject<String>.seeded(null);
    
      TestCubit() : super(TestState(false)) {
        _ss.add(_subscribeToEmailAndPassword());
      }
    
      StreamSubscription _subscribeToEmailAndPassword() {
        return Rx.combineLatest([_emailSubject, _passwordSubject], (list) {
          if (list[0] != null && list[1] != null) {
            return true;
          }
          return false;
        }).listen((value) {
          emit(TestState(value));
        });
      }
    
      @override
      Future<void> close() async {
        _ss.forEach((e) async => await e.cancel());
        await super.close();
      }
    
      void emailFieldChange(String email) {
        _emailSubject.add(email);
      }
    
      void passwordFieldChange(String password) {
        _passwordSubject.add(password);
      }
    }
    

    【讨论】:

    • 就像在另一个答案中一样,我能够使用 RxDart 解决这个问题。我要问的问题是如何在不使用 RxDart 的情况下做到这一点。我想使用“bloc”包或更具体地说,“flutter_bloc”包。我正在尝试确定是否可以使用 flutter_bloc 代替 RxDart。
    猜你喜欢
    • 2020-04-20
    • 2021-11-10
    • 2021-11-04
    • 2020-03-22
    • 2020-04-28
    • 2021-08-10
    • 2021-06-25
    • 2017-07-25
    • 1970-01-01
    相关资源
    最近更新 更多