Clean Architecture中的表单验证



输入验证是一种业务逻辑,因此我们应该将此过程隐藏在域层中。如本文所述

我喜欢这个

登录验证器

class LoginValidator extends Validator {
String email;
String password;
LoginValidator(this.email, this.password);
@override
void validate(Function() success, Function(List<Failure>) errors) {
List<Failure> failures = [];
if (email.trim().isEmpty) {
failures.add(const EmailValidationFailure('Email is required'));
} else if (!validator.isEmail(email)) {
failures.add(const EmailValidationFailure());
}
if (password.trim().isEmpty) {
failures.add(const PasswordValidationFailure('Password is required'));
}
if (failures.isNotEmpty) {
errors(failures);
} else {
success();
}
}
}

我为每个输入字段创建了一个失败类

class EmailValidationFailure extends Failure {
const EmailValidationFailure([String message = 'Email is invalid'])
: super(message);
}
class PasswordValidationFailure extends Failure {
const PasswordValidationFailure([String message = 'Incorrect password'])
: super(message);
} 

我在用例中使用验证器

class LoginUseCaseInteractor implements LoginUseCaseInputPort {
final AccountRepository _repository;
final LoginUseCaseOutputPort outputPort;
LoginUseCaseInteractor(this._repository, this.outputPort);
@override
void login(LoginParams params) {
LoginValidator(params.email, params.password).validate(() async {
outputPort.loading();
Result<bool> result = await _repository.login(params);
result.when(
success: (data) {
outputPort.success();
},
error: (error) {
outputPort.requestError(error);
},
);
}, (errors) {
outputPort.formValidationErrors(errors);
});
}
}

最后,我在演示器中处理演示逻辑,它实现了登录用例的输出端口

class LoginPresenter implements LoginUseCaseOutputPort {
Reader read;
LoginPresenter(this.read) : super(LoginState.initial());
@override
void formValidationErrors(List<Failure> errors) =>
state = LoginState.formValidationErrors(errors);
@override
void success() => read(setRootPresenterProvider.notifier).setMainPageAsRoot();
@override
void loading() => state = LoginState.loading();
@override
void requestError(Failure error) => state = LoginState.requestError(error);
}

我所做的我为每个输入字段创建一个故障类,并返回列表中所有字段的故障,在演示逻辑中,我按类型检查输入故障

我的问题:如果我有一个大表单(例如:15个字段(,我应该为每个表单创建一个失败类吗?是否有更好的方法来处理验证?

我的问题:如果我有一个大表单(例如:15个字段(,我应该为每个表单创建一个失败类吗?是否有更好的方法来处理验证?

每个可能发生的错误都必须是可识别的。通过专用类、故障代码或常量。选择哪一个取决于要提供给客户端的错误上下文信息。

我也不会把消息放在失败对象中,因为由演示者为错误类型选择演示。错误呈现给用户的方式在很大程度上取决于用户界面。也许错误不需要字符串,它只是以图标或彩色标记等形式出现。交互程序不应该创建特定语言的字符串。这是用户界面的一部分。

在简单的情况下,您可能只需要一个错误代码或常量,如401,演示者会将其转换为Login failed。当然,在这种情况下也可以使用一个常见的错误对象。

类故障{int代码;}

在其他情况下,您可能希望显示更详细的错误消息,如E-mails under the domain '@somedomain.com' are not allowed to login.。在这种情况下,您应该使用错误对象,而不是仅使用简单的代码来提供详细信息。例如

类登录域失败{字符串localPart;字符串域名}

然后,演示者可以使用这些信息生成失败字符串或以其他方式显示错误,例如在输入字段中突出显示域名或您可以想象的任何内容。

相关内容

  • 没有找到相关文章

最新更新