代码之家  ›  专栏  ›  技术社区  ›  Basil Bourque

通过定义一对可序列化函数对象,为数据绑定提供转换器

  •  0
  • Basil Bourque  · 技术社区  · 6 年前

    在vaadin 8框架和vaadin 10流中,数据绑定功能允许我们提供 Converter 在小部件期望的数据类型(例如 String 为了一个 TextField )以及backing bean属性的数据类型(例如 Integer 数字)。

    在这个例子中,内置的 转换器 实施 StringToIntegerConverter 使用。

    binder
    .forField( this.phaseField )
    .withConverter( 
        new StringToIntegerConverter( "Must enter an integer number" ) 
    )
    .bind( Panel::getPhase , Panel::setPhase ) ;
    

    但是定义一个 转换器 对于其他类型?我怎么能轻易地定义一个短而甜的 转换器 是吗?例如,字符串- UUID 转换器。我想展示一下 canonical 36-character hex string 在一个 文本字段 往另一个方向走, parse that string back into a UUID .

    // String to UUID
    UUID uuid = UUID.fromString( myString ) ;
    
    // UUID to String
    String myString = uuid.toString() ;
    

    我明白了 Binder.BindingBuilder 提供两种方法 withConverter 两者都需要一对 SerializableFunction 物体。

    • Binder.BindingBuilder:: withConverter (SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation)
    • 绑定生成器: withConverter (SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation, String errorMessage)

    那么我如何定义 SerializableFunction 对象/类?

    我注意到这个接口列出了一个已知的子接口 ValueProvider <SOURCE,TARGET> .这看起来很熟悉,我有一种预感,它是轻松定义一个短的简单转换器的关键。但我并不完全理解lambda的语法以及这里所发生的一切。

    我是 询问如何编写实现类 转换器 .我在问如何写 可序列化函数 传递给的参数 Binder.BindingBuilder::withConverter 以上列出的方法为项目符号项。

    报价 that JavaDoc 以下内容:

    Interface Binder.BindingBuilder<BEAN,TARGET>

    _

    带转换器

    default <NEWTARGET> Binder.BindingBuilder<BEAN,NEWTARGET> withConverter(SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation)

    使用映射函数将绑定映射到另一个数据类型,并将可能的异常作为错误消息。

    映射函数用于在表示类型(必须与绑定的当前目标数据类型匹配)和模型类型(可以是任何数据类型并成为绑定的新目标类型)之间进行转换。调用时 bind(ValueProvider, Setter) ,绑定的目标类型必须与getter/setter类型匹配。

    例如,可以使用适当的函数将文本字段绑定到整型属性,例如: withConverter(Integer::valueOf, String::valueOf);

    类型参数:

    NEWTARGET -要转换为的类型

    参数:

    toModel -可以从旧目标类型转换为新目标类型的函数

    toPresentation -可以从新目标类型转换为旧目标类型的函数

    返回:

    具有适当类型的新绑定

    抛出:

    IllegalStateException -如果已调用绑定

    2 回复  |  直到 6 年前
        1
  •  4
  •   Basil Bourque    6 年前

    可以通过将两个lambda表达式传递给 withConverter ,就像这样:

    binder.forField(textField)
    .withConverter(text -> UUID.fromString(text), uuid -> uuid.toString())
    .bind(/* ... */);
    

    如果需要更复杂的转换,则lambda的右侧可以用括号包围,例如

    binder.forField(textField).withConverter( text -> {
        if ( text == null ) {
           return something;
        } else {
           return somethingElse;
        } 
    }, uuid -> { return uuid.toString(); } )
    .bind(/* ... */);
    
        2
  •  0
  •   Steffen Harbich    6 年前

    如果您多次需要转换器,我建议您创建一个单独的类实现接口。 com.vaadin.data.Converter .但是,正如您已经知道的,使用lambdas也是可能的(请参见@ollitietavinen的答案)。但这不是VAADIN特定的,它是Java 8 +特性,您可以阅读有关 e.g. here .基本上,只要一个对象只需要一个方法来实现接口,就可以使用lambda。

    推荐文章