0

我正在使用 Riverpod 进行状态管理。

class SignInStateNotifier extends StateNotifier<SignInFormStates> {
  SignInStateNotifier(this._authFacade) : super(SignInFormStates.initial());

  final IAuthFacade _authFacade;

  void mapEventToState(SignInFormEvents signInFormEvents) {
    state = signInFormEvents.when(
        emailChanged: (value) => state.copyWith(
              emailAddress: EmailAddress(value),
              authFailureOrSuccess: none(),
            ),
        passwordChanged: (value) => state.copyWith(
              password: Password(value),
              authFailureOrSuccess: none(),
            ),
        signInWithEmailAndPasswordPressed: () async* {
          yield* _performActionOnAuthFacade(
              _authFacade.signInWithEmailAndPassword);
        });
  }

我在这里遇到错误

signInWithEmailAndPasswordPressed: () async* {
              yield* _performActionOnAuthFacade(
                  _authFacade.signInWithEmailAndPassword);
            });

参数类型“Stream Function()”不能分配给参数类型“SignInFormStates Function()”。

我的__performActionOnAuthFacade功能

Stream<SignInFormStates> _performActionOnAuthFacade(
    Future<Either<AuthFailure, Unit>> Function({
      @required EmailAddress emailAddress,
      @required Password password,
    })
        forwardCall,
  ) async* {
    Either<AuthFailure, Unit> failureOrSuccess;
    if (state.emailAddress.isValid() && state.password.isValid()) {
      yield state.copyWith(
        isSubmitting: true,
        authFailureOrSuccess: none(),
      );
      failureOrSuccess = await _authFacade.registerWithEmailAndPassword(
          emailAddress: state.emailAddress, password: state.password);
    }
    yield state.copyWith(
        isSubmitting: false,
        showErrorMessage: true,
        authFailureOrSuccess: optionOf(failureOrSuccess));
  }

请给出解决此错误的解决方案。提前致谢。

4

2 回答 2

2

如果你想用 来做这件事StateNotifier, where 不需要Stream用于改变状态,你需要做这样的事情:

class SignInFormStateNotifier extends StateNotifier<SignInFormState> {
  final IAuthFacade _authFacade;

  SignInFormStateNotifier(this._authFacade) : super(SignInFormState.initial());

  Future handleEvent(SignInFormEvent event) async {
    event.map(
      // email changed
      emailChanged: (event) {
        state = state.copyWith(
          emailAddress: EmailAddress(event.email),
          authFailureOrSuccessOption: none(),
        );
      },
      // password changed
      passwordChanged: (event) {
        state = state.copyWith(
          password: Password(event.password),
          authFailureOrSuccessOption: none(),
        );
      },
      // register with email and password
      registerWithEmailAndPassword: (event) async {
        await _performActionWithEmailAndPassword(
          _authFacade.registerWithEmailAndPassword,
        );
      },
      // sign in with email and password
      signInWithEmailAndPassword: (event) async {
        await _performActionWithEmailAndPassword(
          _authFacade.signInWithEmailAndPassword,
        );
      },
      // sign in with Google
      signInWithGoogle: (event) async {
        state = state.copyWith(
          isSubmitting: true,
          authFailureOrSuccessOption: none(),
        );
        final result = await _authFacade.signInWithGoogle();

        state = state.copyWith(
          isSubmitting: false,
          authFailureOrSuccessOption: some(result),
        );
      },
    );
  }

  Future _performActionWithEmailAndPassword(
    Future<Either<AuthFailure, Unit>> Function({
      @required EmailAddress emailAddress,
      @required Password password,
    })
        action,
  ) async {
    Either<AuthFailure, Unit> result;
    final isEmailValid = state.emailAddress.isValid();
    final isPasswordValid = state.password.isValid();

    if (isEmailValid && isPasswordValid) {
      state = state.copyWith(
        isSubmitting: true,
        authFailureOrSuccessOption: none(),
      );

      result = await action(
        emailAddress: state.emailAddress,
        password: state.password,
      );

      state = state.copyWith(
        authFailureOrSuccessOption: some(result),
      );
    }
    state = state.copyWith(
      isSubmitting: false,
      showErrorMessages: true,
      authFailureOrSuccessOption: optionOf(result),
    );
  }
}
于 2021-01-25T16:35:45.843 回答
0

我不知道你的SignInFormStates班级,但它不希望signInWithEmailAndPasswordPressed调用 Stream 函数,但可能是一个空的 voidCallback ?

state = signInFormEvents.when(
        emailChanged: (value) => state.copyWith(
              emailAddress: EmailAddress(value),
              authFailureOrSuccess: none(),
            ),
        passwordChanged: (value) => state.copyWith(
              password: Password(value),
              authFailureOrSuccess: none(),
            ),
        signInWithEmailAndPasswordPressed: () => () async* {  //so a SignInFormStates Function() calls your stream function
          yield* _performActionOnAuthFacade(
              _authFacade.signInWithEmailAndPassword);
        });

但是仍然有机会在这之后它会给你一些其他错误,告诉你状态期望是类型SignInFormStates并且你传递给它一个流函数,或者它实际上可能等待流完成并返回产生的新状态,唯一的要做的就是尝试看看会发生什么

于 2021-01-23T18:30:01.650 回答