使用Formz实现表单验证遇类型不匹配及属性未定义错误求助
解决Formz表单验证的两个错误
错误1:bool无法赋值给FormzSubmissionStatus?
问题核心是Formz.validate()返回布尔值(验证通过为true,否则为false),但state.copyWith的status参数要求的是FormzSubmissionStatus枚举类型,两者类型不兼容。FormzSubmissionStatus的作用是跟踪表单提交流程状态(初始、正在提交、成功、失败),而非实时验证结果,不能混用。
修复方案
在SignUpState中添加计算属性来判断表单整体有效性,字段更新时仅修改对应字段,不改动status:
修改SignUpState类:
class SignUpState extends Equatable { // 原有代码不变 // 添加计算属性,判断所有字段是否验证通过 bool get isValid => Formz.validate([name, email, password]); @override List<Object> get props => [name, email, password, status]; }
修改SignupController的onNameChange方法:
void onNameChange(String value) { final name = Name.dirty(value); state = state.copyWith( name: name, // 移除原有的status赋值,避免类型不匹配 ); }
错误2:FormzSubmissionStatus没有isValidated getter
FormzSubmissionStatus仅包含提交状态的枚举值,不存在isValidated属性。判断表单是否可提交,需要直接通过字段的验证结果来判断。
修复方案
用SignUpState新增的isValid计算属性判断表单有效性,同时在提交时正确管理提交状态:
修改signUpWithEmailAndPassword方法:
void signUpWithEmailAndPassword() async { // 先校验表单是否有效 if (!state.isValid) return; // 设置提交中状态 state = state.copyWith(status: FormzSubmissionStatus.inProgress); try { // 执行实际注册逻辑(此处替换为API调用) print('Signing up...'); // 注册成功后更新状态 state = state.copyWith(status: FormzSubmissionStatus.success); } catch (e) { // 注册失败时保存错误信息并更新状态 state = state.copyWith( status: FormzSubmissionStatus.failure, errorMessage: e.toString(), ); } }
完整修改后的代码
SignupController
import 'package:flymedia_app/src/auth/signup/controller/signup_state.dart'; import 'package:form_validators/form_validators.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; class SignupController extends StateNotifier<SignUpState> { SignupController() : super(const SignUpState()); void onNameChange(String value) { final name = Name.dirty(value); state = state.copyWith(name: name); } void onEmailChange(String value) { final email = Email.dirty(value); state = state.copyWith(email: email); } void onPasswordChange(String value) { final password = Password.dirty(value); state = state.copyWith(password: password); } void signUpWithEmailAndPassword() async { if (!state.isValid) return; state = state.copyWith(status: FormzSubmissionStatus.inProgress); try { print('Signing up...'); // 替换为实际注册API调用 state = state.copyWith(status: FormzSubmissionStatus.success); } catch (e) { state = state.copyWith( status: FormzSubmissionStatus.failure, errorMessage: e.toString(), ); } } }
SignUpState
import 'package:equatable/equatable.dart'; import 'package:form_validators/form_validators.dart'; class SignUpState extends Equatable { final Name name; final Email email; final Password password; final FormzSubmissionStatus status; final String? errorMessage; const SignUpState({ this.name = const Name.pure(), this.email = const Email.pure(), this.password = const Password.pure(), this.status = FormzSubmissionStatus.initial, this.errorMessage, }); SignUpState copyWith({ Name? name, Email? email, Password? password, FormzSubmissionStatus? status, String? errorMessage, }) { return SignUpState( name: name ?? this.name, email: email ?? this.email, password: password ?? this.password, status: status ?? this.status, errorMessage: errorMessage ?? this.errorMessage, ); } bool get isValid => Formz.validate([name, email, password]); @override List<Object> get props => [name, email, password, status]; }
内容的提问来源于stack exchange,提问作者Jesse Josiah
相关产品推荐
相关产品推荐

