繁体   English   中英

Flutter BloC 从旧版本迁移到 8.0

[英]Flutter BloC migration from old version to 8.0

我正在尝试将 flutter 应用程序从指南制作为具有较新 BloC 版本的更新版本,但是,从旧版本到新版本的更改我遇到了麻烦......

首先,这是我在此阶段尝试在我的应用程序上按“播放”时遇到的错误:

错误的 state:在没有注册事件处理程序的情况下调用了 add(PlayerEvent)。 确保通过 on((event, emit) {...}) 注册处理程序

据我所知,这是因为 mapEventToState 已被弃用,并且从 BloC 8.0.1 开始,我尝试自己进行更改,但是,我是初学者,我无法理解我应该如何去做。

这是我现在已弃用的实际代码

class PlayBloc extends Bloc<PlayEvent, PlayState>{

  final PlayerControl radioPlayer;


  PlayBloc({required this.radioPlayer}) : assert(radioPlayer != null),super(isPausedState());

   @override //Déprécié
  PlayState get initialState => isPausedState();
 
  @override
  Stream<PlayState> mapEventToState(PlayEvent event) async* {
    if(event is PlayerEvent){
      yield isPlayingState();
      await radioPlayer.play(url: event.url);
    }
    else if(event is StopEvent){
      yield isPausedState();
      await radioPlayer.stop();
    }
  }
  
}

可以向我解释如何改变这个吗? 我尝试遵循此处提出的解决方案: Flutter bloc migration due to mapEventToState is not working

但我无法理解所做的更改..

谢谢你

编辑:再次尝试将其更改为 BloC 8.0 标准,仍然没有运气,它在“on( mapEventToState )”上引发错误

参数类型“Future Function(PlayerEvent)”不能分配给参数类型“FutureOr Function(PlayerEvent, Emitter)”。 (文档)

PlayBloc({required this.radioPlayer}) : assert(radioPlayer != null),super(isPausedState()){
    on<PlayerEvent>(mapEventToState);
  }

  //@override //Déprécié
  //PlayState get initialState => isPausedState();
  Future<void> mapEventToState (
      PlayerEvent event
      ) async {
    if (event is PlayerEvent) {
      if (state is isPausedState) {
        await radioPlayer.play(url: event.url);
        emit(isPlayingState());
      } else if (state is isPlayingState) {
        await radioPlayer.stop();
        emit(isPausedState());
      }
    }
  }

试试下面的代码。 在最新版本中,要从 bloc 更新 UI 更改,您必须编写 emit 而不是 yeild 和 async 而不是 async*。

像这样的新方法调用

on((event, emit) async{
      
});
    

你也可以这样调用

on<className>((event, emit) async{
          
});

作为参考,我与您分享了一个我的集团关闭。

class CovidBloc extends Bloc<CovidEvent, CovidState> {
  CovidBloc() : super(CovidInitial()) {
    final ApiRepository _apiRepository = ApiRepository();

    on<GetCovidList>((event, emit) async {
      try {
        print("Event2: $event");
        emit(CovidLoading());
        final mList = await _apiRepository.fetchCovidList();
        emit(CovidLoaded(mList));
        if (mList.error != null) {
          emit(CovidError(mList.error));
        }
      } on NetworkError {
        emit(const CovidError("Failed to fetch data. is your device online?"));
      }
    });
  }
}

该错误表明您需要注册一个添加到 Bloc 构造函数的on(Event, Emitter) 我将采取的第一步是迁移到单个 function。 这就是我要做的:

  1. bloc_concurrency添加到pubspec.yml :这很重要,这样您的新on(Event, Emitter)行为与您的mapEventToState完全相同。
  2. PlayBloc更改为如下内容:
class PlayBloc extends Bloc<PlayerEvent, PlayerState> {
  PlayBloc({required this.radioPlayer}) : assert(radioPlayer != null),super(isPausedState()){
    on<PlayerEvent>(
      mapEventToState,
      transformer: sequential(),
    );
  }

  //@override //Déprécié
  //PlayState get initialState => isPausedState();
  Future<void> mapEventToState (
      PlayerEvent event,
      Emitter<MyState> emit,
      ) async {
    if (event is PlayerEvent) {
      if (state is isPausedState) {
        await radioPlayer.play(url: event.url);
        emit(isPlayingState());
      } else if (state is isPlayingState) {
        await radioPlayer.stop();
        emit(isPausedState());
      }
    }
  }
}

请注意, mapEventToState现在同时接收eventemit 最后一个发射器是 function,您将使用它来更新 Bloc 的 state。

作为参考,这里有一些关于Bloc 的新 API以及如何使用并发的 VeryGoodVentures 的帖子。 然后(无耻插件),这是我不久前写的关于 Bloc 8.0 的教程

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM