flutter - flutter_bloc many Event to many BlocBuilder
问题描述
最近在学习flutter_bloc
,参考了flutter_weather这个项目。
我比较疑惑的是,如果一个Bloc
类有很多Events,而且大部分Event
s都会有返回的值State
,而项目中有很多BlocBuilder
s,如果我想让aBlocBuilder
只响应某一个Event
怎么办?
我能想到的方法就是把这个Bloc
分成多个Bloc
,或者把每个要返回的值当作一个属性Bloc
,BlocBuilder
用buildwhen
方法来判断是否重建。
但这两种方法对我都不好。有什么好的方法吗?最好有项目在github上供参考。
例如:这是事件:</p>
abstract class WeatherEvent extends Equatable {
const WeatherEvent();
}
class WeatherRequested extends WeatherEvent {
final String city;
const WeatherRequested({@required this.city}) : assert(city != null);
@override
List<Object> get props => [city];
}
class WeatherRefreshRequested extends WeatherEvent {
final String city;
const WeatherRefreshRequested({@required this.city}) : assert(city != null);
@override
List<Object> get props => [city];
}
这是状态:</p>
abstract class WeatherState extends Equatable {
const WeatherState();
@override
List<Object> get props => [];
}
class WeatherInitial extends WeatherState {}
class WeatherLoadInProgress extends WeatherState {}
class WeatherLoadSuccess extends WeatherState {
final Weather weather;
const WeatherLoadSuccess({@required this.weather}) : assert(weather != null);
@override
List<Object> get props => [weather];
}
class WeatherLoadFailure extends WeatherState {}
这是集团:</p>
class WeatherBloc extends Bloc<WeatherEvent, WeatherState> {
final WeatherRepository weatherRepository;
WeatherBloc({@required this.weatherRepository})
: assert(weatherRepository != null),
super(WeatherInitial());
@override
Stream<WeatherState> mapEventToState(WeatherEvent event) async* {
if (event is WeatherRequested) {
yield* _mapWeatherRequestedToState(event);
} else if (event is WeatherRefreshRequested) {
yield* _mapWeatherRefreshRequestedToState(event);
}
}
Stream<WeatherState> _mapWeatherRequestedToState(
WeatherRequested event,
) async* {
yield WeatherLoadInProgress();
try {
final Weather weather = await weatherRepository.getWeather(event.city);
yield WeatherLoadSuccess(weather: weather);
} catch (_) {
yield WeatherLoadFailure();
}
}
Stream<WeatherState> _mapWeatherRefreshRequestedToState(
WeatherRefreshRequested event,
) async* {
try {
final Weather weather = await weatherRepository.getWeather(event.city);
yield WeatherLoadSuccess(weather: weather);
} catch (_) {}
}
}
这是 BlocConsumer:
// BlocBuilder1
BlocBuilder<WeatherBloc, WeatherState>(
builder: (context, state) {
if (state is WeatherLoadInProgress) {
return Center(child: CircularProgressIndicator());
}
if (state is WeatherLoadSuccess) {
final weather = state.weather;
return Center(child: Text("WeatherRequested "))
}
)
// BlocBuilder2
BlocBuilder<WeatherBloc, WeatherState>(
builder: (context, state) {
if (state is WeatherLoadInProgress) {
return Center(child: CircularProgressIndicator());
}
if (state is WeatherLoadSuccess) {
final weather = state.weather;
return Center(child: Text("WeatherRefreshRequested"))
}
)
问题是我希望 BlocBuilder1 仅在 Event 类型为 WeatherRequested 时工作,而 BlocBuilder2 仅在 Event 类型为 WeatherRefreshRequested 时工作。我的一个想法是每个Event都有自己的State,然后在buildwhen中判断State的类型。
有什么好的方法吗?
解决方案
如果您想构建您的小部件以响应某些状态,您应该使用 BlocConsumer并在buildWhen中告诉该 bloc 告诉它应该在什么状态下构建/重建您的小部件。
BlocConsumer<QuizBloc, QuizState>(
buildWhen: (previous, current) {
if (current is QuizPoints)
return true;
else
return false;
},
listener: (context, state) {},
builder: (context, state) {
if (state is QuizPoints)
return Container(
child: Center(
child: Countup(
begin: 0,
end: state.points,
duration: Duration(seconds: 2),
separator: ',',
),
),
);
else
return Container();
},
);
推荐阅读
- apache-kafka - 如何测试@onFailure 方法?
- r - 在R Shiny中,第一次调用App时如何消除observeEvent条件的闪烁?
- javascript - 检测旧的 Internet Explorer Javascript 函数(< ES6)
- react-native - 如何在缩略图中使用带有来自 json 文件的道具的本地图像?
- kotlin - Solo 学习如何在 Kotlin 中根据一些条件计算停车费
- javascript - 如何在 React JS 中使用 Link 传递 id
- python - 使用 sklearn 的 Kmeans 获得更好的结果
- autodesk-forge - 在查看器 v7.51 中使用 Autodesk.NPR 中的石墨模式时选择不可见
- python-3.x - 使用 Python 查找在给定日期范围内具有最小值的列名列表
- c++ - Ultisnips Neovim - 带有 strftime() 的时间戳不断变化