如何在 Vaadin 8 中添加验证器?

How to add Validators in Vaadin 8?

Vaadin 7 中有 addValidator 函数,但在 Vaadin 8 中不存在。

Vaadin 7 示例:

   TextField user = new TextField("User:");
   user.setRequired(true);
   user.setInputPrompt("Your username");
   user.addValidator(new NullValidator("Username can't be empty", false));
   user.setInvalidAllowed(false);

我在这里找到了答案:Whats New

示例:

new Binder<Person>().forField(tf)
    .withValidator(str -> str.length() == 4, "Must be 4 chars")
    .withConverter(new StringToIntegerConverter("Must be Integer"))
    .withValidator(integer -> integer.equals(2017), "Wrong date")
    .bind(Person::getBirthYear, Person::setBirthYear);

looks correct. That code looks to be taken from this very brief (3 minutes) but very helpful video published by the Vaadin company, Type safe validation before and after converters。显示新的 Vaadin 8 验证方法。我将添加一些注释、显示扩展的语法并提供完整的示例代码以实现完整的工作应用程序。

验证器 + 绑定器

Vaadin 8 的一大区别是 验证器需要 use of a binder. In the old days, you attached a validator to a field, but now in Vaadin 8 you attach a validator only to a binder. The Vaadin team recognizes that for some simple situations this requirement of a binder may prove annoying, but for the most part they sensibly expect situations needing validation are quite likely also doing binding. A very logical re-think, I believe. Discussed in another Vaadin company video, Webinar: What's new in Vaadin 8?.

验证和转换器

我们定义了两个不同的验证器,一个在转换器转换用户数据输入之前调用,另一个在转换后调用。因此,流畅风格的 withValidatorwithConverter 方法调用的顺序是纠正此处行为的关键。当然 beforeConversionafterConversion 是验证器对象的糟糕名称,但这样做是为了明确本演示中转换器之前或之后的 运行 的意图。

Lambda synax 可选

一个验证器使用传统的 Java 代码风格覆盖方法。另一个验证器使用 Lambda 语法。观看视频并查看 ,了解使用单行 Lambda 参数进一步简化的代码。

package com.example.valapp;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.data.Binder;
import com.vaadin.data.ValidationResult;
import com.vaadin.data.Validator;
import com.vaadin.data.ValueContext;
import com.vaadin.data.converter.StringToIntegerConverter;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.*;

import javax.servlet.annotation.WebServlet;


/**
 * This UI is the application entry point. A UI may either represent a browser window
 * (or tab) or some part of a html page where a Vaadin application is embedded.
 * <p>
 * The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be
 * overridden to add component to the user interface and initialize non-component functionality.
 */
@Theme ( "mytheme" )
public class MyUI extends UI {

    @Override
    protected void init ( final VaadinRequest vaadinRequest ) {

        final TextField tf = new TextField ( "Enter year of birth:" );

        Validator<String> beforeConversion = new Validator < String > ( ) {
            @Override
            public ValidationResult apply ( String s, ValueContext valueContext ) {
               if(s.length ()!= 4) {
                   return  ValidationResult.error ( "Year must consist of 4 digits" );
               } else {
                   return  ValidationResult.ok () ;
               }
            }
        } ;

        Validator<Integer> afterConversion = Validator.from ( value -> value.equals ( 2017 ), "Wrong year." );

        new Binder < Person > ( )
                .forField ( tf )
                .withValidator ( beforeConversion )
                .withConverter ( new StringToIntegerConverter ( "Input must be Integer" ) )
                .withValidator ( afterConversion )
                .bind ( Person:: getYearOfBirth, Person:: setYearOfBirth );

        Button button = new Button ( "Tell me" );
        button.addClickListener ( event -> Notification.show("This is the caption", "This is the description", Notification.Type.HUMANIZED_MESSAGE) );

        setContent ( new VerticalLayout ( tf  , button ) );
    }

    @WebServlet ( urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true )
    @VaadinServletConfiguration ( ui = MyUI.class, productionMode = false )
    public static class MyUIServlet extends VaadinServlet {
    }
}

What if you don't have a binder due to creating a dynamic form?

Vaadin 8.1 支持删除支持动态表单的字段的活页夹。 如果您使某个字段不可见,则删除该字段的活页夹。 Re-add 使字段可见时的活页夹。