我正在尝试使用视频Flutter/AngularDart中描述的BLoC模式构建一个Flutter应用程序- 代码共享,更好地在一起(DartConf 2018)
BLoC基本上是一个带Sink输入和Stream输出的视图模型.在我的例子中,它看起来有点像这样:
class BLoC {
// inputs
Sink<String> inputTextChanges;
Sink<Null> submitButtonClicks;
// outputs
Stream<bool> showLoading;
Stream<bool> submitEnabled;
}
Run Code Online (Sandbox Code Playgroud)
我在层次结构根目录附近的小部件中定义了BLoC,并将其传递给它下面的小部件,包括嵌套的小部件StreamBuilders.像这样:
顶部StreamBuilder监听showLoadingBLoC上的流,以便它可以重建以显示重叠的进度微调器.底部StreamBuilder侦听submitEnabled流以启用/禁用按钮.
问题是当showLoading流导致top StreamBuilder重建窗口小部件时,它也会重建嵌套窗口小部件.这本身就很好并且预期.然而,这导致底部StreamBuilder被重新创建.当发生这种情况时,它会尝试重新订阅submitEnabledBLoC上的现有流Bad state: Stream has already been listened to
有没有办法在不进行所有输出的情况下实现这一目标BroadcastStreams?
(我也有可能从根本上误解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: …Run Code Online (Sandbox Code Playgroud) 在模块内部,如果我需要基于模块构造时已知的变量提供接口的不同实现,我可以将逻辑放在@Provides方法中用于该接口类型.像这样:
@Module
public class FooModule {
private final State state;
public FooModule(State state) {
this.state = state;
}
@Provides
FooInterface provideFooImplementation() {
switch(state) {
case STATE_1:
return new FooImpl1();
case STATE_2:
return new FooImpl2();
...
case STATE_10:
return new FooImpl10();
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这些实现可以由Dagger创建.我宁愿说"嘿,基于XI希望你为我实例化这个课程"
我考虑了几个选择.
更改提供方法以接受所有可能的实现:
@Provides
FooInterface provideFooImplementation(FooImpl1 impl1, FooImpl2 imp2, ..., FooImpl10 impl10) {
switch(state) {
case STATE_1:
return impl1;
case STATE_2:
return impl2;
...
case STATE_10:
return impl10;
}
}
Run Code Online (Sandbox Code Playgroud)这允许Dagger实例化它们并满足它们的所有依赖关系,但是如果每个实现都相对较大或者创建起来很昂贵,那么这不是一个好主意.
更改提供方法以接收不同实现的所有依赖关系的集合.
@Provides
FooInterface provideFooImplementation(Context context, Repo …Run Code Online (Sandbox Code Playgroud)