flutter 为什么BlocListener不监听我的状态?

cwtwac6a  于 2023-05-19  发布在  Flutter
关注(0)|答案(1)|浏览(146)

有点奇怪的是,blocListener没有监听我的状态变化,我的状态永远是null,为什么会这样?
一点帮助或见解将不胜感激。
user_cubit.dart

UserCubit() : super(UserInitialState()) {
    emit(UserMainLoadingState());
    _firestore
        .collection("users")
        .doc(_currentUser?.uid) // or whatever your collection name is
        .snapshots()
        .listen((event) {
      event.exists
          ? {
              print("User Exists"),
              emit(state.copyModel(
                  userModel: UserModel.fromjson(event.data()!, event.id))), // Here I am using copyModel , as a additional method
              emit(UserExists(
                  userModel: UserModel.fromjson(event.data()!, event.id)))
            }
          : {print("There is no such user"), emit(UserNotExists())};
    });
  }

user_state.dart

class UserState extends Equatable {
  final UserModel? userModel;
  const UserState({this.userModel});

  UserState copyModel({required UserModel userModel}) {
    return UserState(userModel: userModel);
  }

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

class UserExists extends UserState {
  UserExists({required UserModel userModel}) : super(userModel: userModel) {

  }
}

my_widget.dart

body: BlocListener<UserCubit, UserState>(
          listener: (context, state) {
              print("I am inside the listener");
            if (state.userModel != null) {
              print("State is ${state.runtimeType}");

            }
          },
          child: <My widget>

console

I/flutter ( 5029): I am inside the UserExists state and the user is :avatar boy
I/flutter ( 5029):  fullName krrrt
I/flutter ( 5029):  dob 19/1/2022
I/flutter ( 5029):  email rd@xddf.co
I/flutter ( 5029):  phone 12222222255

令人惊讶的是,打印I am inside the listener从未执行。
listener中,我想初始化一些变量,比如textfield,但是我的状态总是空的,我不知道为什么,尽管我已经更新了状态,并且状态里面有值。
一点帮助将不胜感激
编辑:
User_model.dart

class UserModel {
  final String avatar;
  final String fullName;
  final String phoneNumber;
  final String dob;
  final String email;
  String? id;

  UserModel(
      {required this.avatar,
      required this.dob,
      required this.email,
      required this.fullName,
      required this.phoneNumber});

  factory UserModel.fromjson(Map<String, dynamic> json, String id) {
    return UserModel(
        avatar: json['avatar'],
        dob: json["dob"],
        email: json['email'],
        fullName: json['fullName'],
        phoneNumber: json['phoneNumber']);
  }
  Map<String, dynamic> toJson() {
    return {
      'fullName': fullName,
      'dob': dob,
      'avatar': avatar,
      'email': email,
      'phoneNumber': phoneNumber,
    };
  }

  @override
  String toString() {
    // TODO: implement toString
    return "avatar $avatar \n fullName $fullName \n dob $dob \n email $email\n phone $phoneNumber ";
  }
}
wf82jlnq

wf82jlnq1#

执行extends Equatable时需要覆盖的UserStateprops用于通过先前和当前状态UserState的相等性来比较触发差异,以便发出它。
对于像intString ...这样的原语,你不需要担心它们,因为它们已经有了自己的==,来自Dart SDK:
这对于你创建的自定义类是不正确的,当创建一个UserModel类时,它没有==关系,所以当UserCubitemit()试图比较以前和当前的UserState时,是什么告诉它不同的是比较props,对吗?所以在您的例子中,它将比较props元素,这些元素只有UserModel

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

现在这里是技巧,你可以尝试自己手动比较两个userModel

final first = userModel(/* properties */);
final second = userModel(/* same properties as first's */);

first == second // false

即使它们具有相同的属性,它们也总是无法比较它们并返回false,每次比较两个UserState时,它都是相同的,并且emit()将被忽略,这不会触发BlocListener
解决方案是,你需要定义userModel的相等关系,你还需要使用Equatable

class UserModel extends Equatable { // add this
//...

@override
List<Object?> get props => [avatar, fullName, phoneNumber, dob, email];
}

相关问题