简体   繁体   English

事件管理 flutter 集团模式

[英]events management flutter bloc pattern

everyone.每个人。 I am new in Flutter and BLoC pattern.我是 Flutter 和 BLoC 模式的新手。

I needed to implement contact page so I created event GetContacts and passed it into context.read().add() after that I called this event into initState() of contacts screen.我需要实现联系人页面,所以我创建了事件 GetContacts 并将其传递给 context.read().add() 之后我将此事件调用到联系人屏幕的 initState() 中。

Here my event:这是我的活动:


abstract class ContactEvent extends Equatable {
  const ContactEvent([List props = const []]) : super();
}

class GetContacts extends ContactEvent {

  const GetContacts() : super();

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

Here is my bloc:这是我的集团:

class ContactsBloc extends Bloc<ContactEvent, ContactsState> {
  final ContactsRepo contactsRepo;
  ContactsBloc({required this.contactsRepo}) : super(ContactInitial());

  @override
  Stream<ContactsState> mapEventToState(ContactEvent event,) async* {
    yield ContactsLoading();
    //
    // if (event is UpdatePhoto) {
    //   yield PhotoLoading();
    //
    //   print("LOADING STARTED");
    //
    //   final photo = await contactsRepo.updatePhoto(event.identifier, event.photo);
    //   print("LOADING FINISHED");
    //
    //   yield PhotoLoaded(photo: photo);
    // }
    if (event is GetContacts) {
      print("get contacts photoBloc");
      try {

        final contacts = await contactsRepo.getContacts();
        yield ContactsLoaded(contacts);
      } on AccessException {
        yield ContactsError();
      }
    }
  }
} 

That works right and contacts page renders contacts as it is supposed.这工作正常,联系人页面按预期呈现联系人。

[contacts screen][1] [1]: https://i.stack.imgur.com/Gx3JA.png [联系人屏幕][1] [1]:https://i.stack.imgur.com/Gx3JA.png

But then I decided to implement new feature: when user clicks on any contact he is offered to change its photo.但后来我决定实现新功能:当用户点击任何联系人时,他会被要求更改其照片。 If I understand BLoC pattern correctly then if I want to change my state I need to create new event.如果我正确理解 BLoC 模式,那么如果我想更改我的 state,我需要创建新事件。 Then I created new action UpdatePhoto and passed it into the same Bloc as it shown at 2nd part of code (in comments).然后我创建了新动作 UpdatePhoto 并将其传递到与代码第二部分(在注释中)所示的相同的 Bloc 中。 Exactly there I encounter a misunderstanding of architecture expansion.正是在那里,我遇到了对架构扩展的误解。 This action is not supposed to return ContactsLoaded state so when I tried to catch this into my another bloc builder it broke my previous bloc builder that caught GetContact event.此操作不应该返回 ContactsLoaded state 所以当我试图将其捕获到我的另一个 bloc 构建器中时,它破坏了我之前捕获 GetContact 事件的 bloc 构建器。

ContactState:联系状态:

abstract class ContactsState extends Equatable {
  const ContactsState([List props = const []]) : super();
}


// class PhotoLoading extends PhotoState {
//   @override
//   List<Object?> get props => [];
// }
//
// class PhotoLoaded extends PhotoState {
//   final Uint8List photo;
//   const PhotoLoaded({required this.photo});
//   @override
//   List<Object?> get props => [photo];
// }

class ContactInitial extends ContactsState {
  @override
  List<Object> get props => [];
}

class ContactsLoading extends ContactsState {
  @override
  List<Object> get props => [];
}

class ContactsLoaded extends ContactsState {
  final List<MyContact> contacts;
  ContactsLoaded(this.contacts) : super([contacts]);

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

class ContactsError extends ContactsState {
  @override
  List<Object?> get props => [];
}

Question: If I want to create new event (for example UpdatePhoto) which is not supposed to return the state that I caught before at the same bloc then I need to create new bloc for that purpose and cover my screen by multiProvider?问题:如果我想创建不应该返回我之前在同一个区域中捕获的 state 的新事件(例如 UpdatePhoto),那么我需要为此目的创建新区域并通过 multiProvider 覆盖我的屏幕?

You should also post your ContactState code.您还应该发布您的 ContactState 代码。

However you do not necessarely need a new Bloc.但是,您不一定需要新的 Bloc。 It all depends on what you are trying to achieve.这完全取决于您要达到的目标。 I suppose than when you yield PhotoLoading() you want to show a loader.我想当你yield PhotoLoading()时,你想显示一个加载器。 But when you update the photos, if I understand what you are trying to achieve you should yield an updated list of contacts using again yield ContactsLoaded(contacts) or add(GetContacts()) instead of yield PhotoLoaded(photo: photo) .但是,当您更新照片时,如果我了解您要达到的目标,您应该再次使用yield ContactsLoaded(contacts)add(GetContacts())而不是yield PhotoLoaded(photo: photo)来生成更新的联系人列表。 If you want to show a confirmation message, you can keep your PhotoLoaded state, but you need to build your UI taking into account the different state the bloc may emit.如果您想显示确认消息,您可以保留 PhotoLoaded state,但您需要在构建 UI 时考虑到该集团可能发出的不同 state。

Remember in BloC architecture event can yield to multiple states in successions and the UI decide if and how to react to each state.请记住,在 BloC 架构中,事件可以连续产生多个状态,并且 UI 决定是否以及如何对每个 state 做出反应。

I guess use optional parameter buildWhen in BlocBuilder is the best way to avoid creating new bloc for each event.我想在 BlocBuilder 中使用可选参数 buildWhen 是避免为每个事件创建新块的最佳方法。

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

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