Bloc从7.2.1升级到8.1.0:自定义EventTransformer迁移异常求助
Bloc 8.x 升级后防抖转换器失效的解决方案
你的实现存在两个核心问题:
未调用事件处理映射器(mapper)
Bloc 8.x 的EventTransformer职责是将处理后的事件流转换为状态流,必须通过传入的mapper(即事件处理函数)生成状态。你之前的代码直接返回事件流,导致事件未被处理成状态,自然达不到预期效果。事件流范围不匹配
若将转换器绑定在单个事件类型的on方法中(比如on<SelectTab>),该转换器的events流仅包含SelectTab类型事件,原代码中!(event is SelectTab)的筛选条件永远为假,导致others流为空,逻辑完全失效。
解决方案一:全局事件转换(对应原 7.x 中 transformEvents 的用法)
如果需要对整个 Bloc 的所有事件应用防抖逻辑,在 Bloc 构造时指定全局 eventTransformer:
修正后的转换器代码
EventTransformer<FavouriteEvent> changeTabTransformer(Duration duration) { return (Stream<FavouriteEvent> events, mapper) { // 对需要防抖的事件做延迟处理 final debouncedTabEvents = events .where((event) => event is SelectTab && event.animatePage == false) .debounceTime(duration); // 其他事件直接放行 final immediateEvents = events.where((event) => (event is SelectTab && event.animatePage == true) || !(event is SelectTab)); // 合并流后通过 mapper 转换为状态流 return MergeStream([debouncedTabEvents, immediateEvents]).switchMap(mapper); }; }
在 Bloc 中使用全局转换器
class FavouriteBloc extends Bloc<FavouriteEvent, FavouriteState> { FavouriteBloc() : super(FavouriteInitialState(), // 指定全局事件转换器 eventTransformer: changeTabTransformer(Duration(milliseconds: 100)) ) { // 注册所有事件处理逻辑 on<SelectTab>(_handleSelectTab); on<OtherFavouriteEvent>(_handleOtherEvent); // ...其他事件 } void _handleSelectTab(SelectTab event, Emitter<FavouriteState> emit) { // 处理 SelectTab 事件逻辑 } void _handleOtherEvent(OtherFavouriteEvent event, Emitter<FavouriteState> emit) { // 处理其他事件逻辑 } }
解决方案二:针对单个事件类型的转换
如果仅需要对 SelectTab 事件应用防抖逻辑,调整转换器逻辑并绑定到对应事件的 on 方法:
修正后的转换器代码
EventTransformer<SelectTab> changeTabTransformer(Duration duration) { return (Stream<SelectTab> events, mapper) { // 仅处理 SelectTab 事件,区分是否需要防抖 final debouncedEvents = events .where((event) => !event.animatePage) .debounceTime(duration); final immediateEvents = events.where((event) => event.animatePage); return MergeStream([debouncedEvents, immediateEvents]).switchMap(mapper); }; }
在事件处理中使用转换器
class FavouriteBloc extends Bloc<FavouriteEvent, FavouriteState> { FavouriteBloc() : super(FavouriteInitialState()) { // 仅对 SelectTab 事件应用转换器 on<SelectTab>(_handleSelectTab, transformer: changeTabTransformer(Duration(milliseconds: 100)) ); // 其他事件正常处理 on<OtherFavouriteEvent>(_handleOtherEvent); } void _handleSelectTab(SelectTab event, Emitter<FavouriteState> emit) { // 处理 SelectTab 事件逻辑 } }
内容的提问来源于stack exchange,提问作者cipli onat
相关产品推荐
相关产品推荐

