Dart 将多个行为主题流合并为一个?

Dart 将多个行为主题流合并为一个?,dart,rxdart,Dart,Rxdart,我的目标是使用多个流,而不必嵌套3+个StreamBuilder 我已经在使用rxdart了,我研究了mergewith,但是我真的不理解使用它的正确语法 我目前有一个名为InfoBloc的Bloc文件。这是InfoBloc final _name = BehaviorSubject<String>(); final _description = BehaviorSubject<String>(); final _picture = BehaviorSubje

我的目标是使用多个流,而不必嵌套3+个StreamBuilder

我已经在使用rxdart了,我研究了mergewith,但是我真的不理解使用它的正确语法

我目前有一个名为
InfoBloc
的Bloc文件。这是
InfoBloc

  final _name = BehaviorSubject<String>();
  final _description = BehaviorSubject<String>();
  final _picture = BehaviorSubject<File>();

  Observable<String> get name => _name.stream.transform(_validateName);
  Observable<File> get picture => _picture.stream;
  Observable<String> get eventDescription =>
      _description.stream.transform(_validateMessage);

  final _validateMessage = StreamTransformer<String, String>.fromHandlers(
      handleData: (eventMessage, sink) {
    if (eventMessage.length > 0) {
      sink.add(eventMessage);
    } else {
      sink.addError(StringConstant.eventValidateMessage);
    }
  });

  var obs = Observable.merge([])
  final _validateName = StreamTransformer<String, String>.fromHandlers(
      handleData: (String name, sink) {
    if (RegExp(r'[!@#<>?":_`~;[\]\\|=+)(*&^%0-9-]').hasMatch(name)) {
      sink.addError(StringConstant.nameValidateMessage);
    } else {
      sink.add(name);
    }
  });

  void dispose() async {
    await _description.drain();
    _description.close();
    await _name.drain();
    _name.close();
    await _picture.drain();
    _picture.close();
  }
final_name=BehaviorSubject();
最终描述=行为主体();
最终图片=行为主体();
可观察的get name=>\u name.stream.transform(\u validateName);
可观察的获取图片=>\u picture.stream;
可观察的get eventDescription=>
_description.stream.transform(_validateMessage);
最终_validateMessage=StreamTransformer.fromHandlers(
handleData:(事件消息,接收器){
如果(eventMessage.length>0){
sink.add(eventMessage);
}否则{
sink.addError(StringConstant.eventValidateMessage);
}
});
var obs=可观察的。合并([])
final _validateName=StreamTransformer.fromHandlers(
handleData:(字符串名称,接收器){
if(RegExp(r'[!@#?“:\`~;[\]\\\\\\\\\\\\\\\\\=+)(*&^%0-9-]).hasMatch(name)){
sink.addError(StringConstant.nameValidateMessage);
}否则{
添加(名称);
}
});
void dispose()异步{
等待_description.drain();
_description.close();
等待_name.drain();
_name.close();
等待图片。排水管();
_picture.close();
}
现在,在一个小部件中,我需要名称、图片和描述快照

 StreamBuilder(
   stream: _bloc.name,
   builder: (BuildContext context, AsyncSnapshot<String> snapshotName) {
     return StreamBuilder(
       stream: _bloc.eventDescription,
       builder: (BuildContext context, AsyncSnapshot<String> snapshotDescription) {
         return StreamBuilder(
           stream: _bloc.picture,
           builder: (BuildContext context, AsyncSnapshot<File> snapshotName) {
StreamBuilder(
流:_bloc.name,
生成器:(BuildContext上下文,异步快照快照名称){
返回流生成器(
流:_bloc.eventDescription,
生成器:(BuildContext上下文,异步快照快照描述){
返回流生成器(
流:_bloc.picture,
生成器:(BuildContext上下文,异步快照快照名称){
但必须有更好的方法来做到这一点


我的梦想是我可以在
InfoBloc
文件中制作一些东西来合并所有这些流,我只需要使用StreamBuilder一次就可以对合并后的流进行流处理。

您可以查看
CombineTest()
可观测类的方法。它使用组合器函数将给定的流合并成一个可观测序列,这样,除非所有流至少发射了一个项目,否则生成的可观测序列不会发射

有很多方法。但是由于您有3个流,您可以使用
combinelatetest3()

范例-

Observable.combineLatest3(
  new Observable.just("a"),
  new Observable.just("b"),
  new Observable.fromIterable(["c", "c"]),
  (a, b, c) => a + b + c)
.listen(print); //prints "abc", "abc"
您可以查看链接以了解更多信息

更新-

关于在代码中使用函数,可以参考下面的示例

Observable<String> get name => _name.stream.transform(_validateName);
Observable<File> get picture => _picture.stream;
Observable<String> get eventDescription => _description.stream.transform(_validateMessage);
//Add this line to combine your Streams
Observable<bool> readyToSubmit => Observable.combineLatest3(name, picture, eventdescription, (value1, value2, value3) => true);
//We simply return true from the combiner function since we don't want to perform any operation on the Streams when combining.

希望这有帮助!

如果只有一小部分流发出项目,例如只有2个流发出,而第3个流从未发出……那么组合流没有任何结果吗?是的,除非每个流至少发出一次,否则组合流不会发出结果。您可以参考此内容以更好地理解。如果您不确定关于任何一个发送数据的流,那么您只能使用
combineLatest2()
组合两个流,并分别使用第三个流。当您不确定流是否发出数据时,没有解决方案吗?您总是要测试流吗?对于初学者的问题,对不起,我是一个反应式编程Nooby您可以使用
startsWith()
方法,以确保您的可观察对象具有一些初始数据,然后您可以使用
comineLatest()
方法。有关此方法的更多信息。感谢示例和注释!我唯一的问题是我应该将其放置在何处?以及您何时编写(a、b、c)=>a+b+c,它如何知道a、b和c是什么?我如何使用它而不是StreamBuilder?
StreamBuilder(
   stream: _bloc.readyToSubmit,
   builder: //Your builder function here
)