这个问题来自我之前的Inline validation using JSR-303 in GWT, part 1: Validation on TextBox fails. Why?,其中我描述了首次尝试使用JSR-303进行内联验证的失败,并请求帮助理解它为什么不起作用。< / p>
我使用的主要文档是 GWT validation dev guide 和JSR-303 spec。
我的第二次尝试将约束定义移动到界面中:
import javax.validation.constraints.Pattern;
public interface FooValidation {
@Pattern(regexp="^[0-9]+$", message="Foo: expected digits.")
public String getFoo();
}
MyValidatorFactory
现在指定要验证FooValidation
接口
@GwtValidation(FooValidation.class)
public interface GwtValidator extends Validator {
}
和我的TextBox
实现了定义JSR-303约束的接口:
public class FooWidget extends TextBox implements FooValidation {
public String getFoo() {
return getValue(); // from TextBox
}
}
该字段使用UiBinder
:
<my:FooWidget ui:field="foo"></my:FooWidget>
并以通常的方式包含在我的表单小部件中:
@UiField
FooWidget foo;
然后可以在布尔上检查约束,例如:
@UiHandler("foo")
void onBlur(BlurEvent ev) {
// Need to cast (code smell?) to FooValidation,
// because that is the class set up for validations
Set<ConstraintViolation<FooValidation>> violations =
validator.validate((FooValidation)foo);
for (ConstraintViolation<FooValidation> violation : violations) {
// TODO - report violation.getMessage() to user
}
}
现在,这似乎有效(基于昨天非常有限的烟雾测试!)。
但这种方法感觉有点费力。
我已经介绍了两件新的&#39;文物&#39; (FooWidget
和FooValidation
)只是为验证机制提供服务,
这与Occam's Razor的剪辑相反!
我错过了一些更简单的东西吗?
在我继续使用这种模式实现大量验证之前,我非常有兴趣了解任何陷阱,
以及其他人使用JSR-303在GWT中进行内联验证的经验。
我希望我可以改进上面的方法,并梳理出一些通用的抽象, 但是,在继续沿着这条路走下去之前,知道我是否错过了一些东西会很好。
答案 0 :(得分:0)
由于这个问题仍然没有答案,我发布的答案反映了我们的决定。
@Thomas Broyer指出here“GWT-Validation几乎没有维护”。因此,我们决定发展自己的想法,借用这样的想法:当验证器执行验证时,它会返回一组违规,但也会在触发验证器时添加控制权。
以下是使用我们自己开发的验证框架的代码示例。我们有一个表单,用户可以在其中指定出站和入境旅程的日期和时间。我们希望将出站时间限制在过去最多15分钟,并且在入站时间之前(实际上,这只是略微过度简化,但希望足以理解此示例背后的要求)。
// Check that we're not returning from our destination before we get there.
// Create a Validator that can get DateTime from two widgets
// (both implement HasValue<DateTime>) so that it may compare
// two DateTime values:
JourneyDateTimeValidator journeyDateTimeValidator
= new JourneyDateTimeValidator(outboundDateTime, inboundDateTime);
// Add a constraint with an error message for when it is violated:
journeyDateTimeValidator.addConstraint(
new JourneyDateTimeValidator.Constraint(
MESSAGES.mustNotLeaveBeforeArriving()));
// Create a Validator to check that a DateTime is not in the past:
ValueValidator<DateTime> outboundValidator
= new ValueValidator<DateTime>(outboundDateTime);
// outboundDateTime must be no more than 15 mins in the past.
final int N = 15;
// Add a constrint to the validator,
// to check the DateTime value is no more than N minutes in the past.
// The NotInThePastConstraint is an example of a special-purpose constraint,
// but, of course there are many general-purpose ones. We can add many
// Constraints to the same Validator. This is similar specification
// of a list of Constraints in JSR-303.
outboundValidator.addConstraint(new NotInThePastConstraint(N*60*1000, // ms
MESSAGES.mustNotBeInThePast()));
// outboundValidityIndicator is a GWT Label that can display
// a Tick, or a Cross with an error message, or nothing.
// We set up Triggers, each of which can have a list of Validators
// to be run when the Trigger fires.
// The ValidityIndicator refreshes its display
// based on the list of Violations returned by the Validators.
outboundValidityIndicator.getTriggers().onValueChange(outboundDateTime)
.addValidator(outboundValidator)
.addValidator(journeyDateTimeValidator);
// We also want the same Validators triggered when inboundDateTime changes:
outboundValidityIndicator.getTriggers().onValueChange(inboundDateTime)
.addValidator(outboundValidator)
.addValidator(journeyDateTimeValidator);
// We keep a list of all ValidatityIndicators in our form,
// so we can get them all to refresh at once
// (we may do this, for example, onMouseOver of the form's submit button):
formValidatorList.add(outboundValidityIndicator);