Dart bloc 8.1 和 Stream

问题描述 投票:0回答:1

最近一直在将旧代码转换成BLOC 8.1版本,遇到了下一个问题。该应用程序是多线程的,并且 mapEventToState 方法用完了流,重要的是,yield 使用了。 例子:

          BlocBuilder<NewsBloc, NewsState>(builder: (context, state) {
        switch (state.status) {
          case NewsStatus.failure:
            return const Center(
                child: Text('FAILD'));
          case NewsStatus.newMessage:
            return messageList(objNews);
          case NewsStatus.success:
            return messageList(objNews);
          default:
            return const Center(child: CircularProgressIndicator());
        }
      }

问题是他 on(mapEventToState) 需要一个 Future 而我需要它是带有 yield 的流。

新闻集团

class NewsBloc extends Bloc<NewsEvent, NewsState> {
NewsBloc(...)
        super(NewsState()) {
    on<NewsEvent>(mapEventToState);
  }

 @override
  Stream<NewsState> mapEventToState(NewsEvent event) async* {
    if (event is NewsInitial) {
      yield await mapNewsInitialToState(state);
    }
    if (event is NewsFetched) {
      yield await _mapNewsFetchedToState(state);
    }
    if (event is MessageReceived) {
      yield await _mapMessageReceivedToState(state, event);
    }
    if (event is NewsClear) {
      yield await mapNewsClearToState(state);
    }
    if (event is MessageRead) {
      yield await mapMessageReadToState(state, event);
    }
  }
}

  Future<ChatListState> mapNewsInitialToState(NewsState state) async {
    try {
      final rooms = await services!.getRoomsList();
      return state.copyWith(
        status: NewsStatus.success,
        rooms: rooms,
          state: state
      );
    } catch (e, s) {
      print('$e, stacktrace: $s');
      return state.copyWith(status: NewsStatus.failure,state: state);
    }
  }

新闻状态

enum NewsStatus { initial, success, failure, newMessage }

class NewsState extends Equatable {
  NewsStatus? status;
   List<NewsRoom>? rooms;
   bool? hasReachedMax;
   bool? isNew;

   NewsState({
    this.status = NewsStatus.initial,
    this.rooms = const <NewsRoom>[],
    this.hasReachedMax = false,
    this.isNew = false,
  });

  NewsState copyWith({
    @required NewsStatus? status,
    @required List<NewsRoom>? rooms,
    @required bool? hasReachedMax,
    @required bool? isNew,
    required NewsState state
  }) {
    state.status = status ?? this.status ;
    state.rooms = rooms ?? this.rooms;
    state.hasReachedMax = hasReachedMax ?? this.hasReachedMax;
    state.isNew = isNew ?? this.isNew ;
   return state;
  }

  @override
  String toString() {
    return '''NewsState { status: $status, hasReachedMax: $hasReachedMax, rooms: ${rooms!.length}, isNew: $isNew, }''';
  }

  @override
  List<Object?> get props => [status, rooms, hasReachedMax, isNew];
}

class MessageReceivedState extends NewsState {
  final ChatMessage? chatMessage;

  MessageReceivedState({@required this.chatMessage});

  @override
  List<Object?> get props => [chatMessage];
}

有谁知道如何同时保持流,以便代码与 BLOC 8.1 一致?

flutter dart mobile stream bloc
1个回答
0
投票

BLoC 8 使用

Emitter
而不是带有
Stream
yield
s。尝试更改
mapEventToState
签名并将
yield
替换为
Emitter
调用。

大致应该是这样的:

void mapEventToState(
  NewsEvent event,
  Emitter<NewsState> emit,
) async {
  if (event is NewsInitial) {
    emit(await mapNewsInitialToState(state));
  } else if (event is NewsFetched) {
    emit(await _mapNewsFetchedToState(state));
  } else if (event is MessageReceived) {
    emit(await _mapMessageReceivedToState(state, event));
  } else if (event is NewsClear) {
    emit(await mapNewsClearToState(state));
  } else if (event is MessageRead) {
    emit(await mapMessageReadToState(state, event));
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.