在Vaadin 8 Framework和Vaadin 10 Flow中,数据绑定功能使我们能够提供Converter
来在小部件的预期数据类型(例如String
的{{1}}之间进行中介)以及后备bean属性的数据类型(例如TextField
号)。
在此示例中,使用了内置的Integer
实现StringToIntegerConverter
。
Converter
但是为其他类型定义binder
.forField( this.phaseField )
.withConverter(
new StringToIntegerConverter( "Must enter an integer number" )
)
.bind( Panel::getPhase , Panel::setPhase ) ;
呢?如何轻松定义简短的Converter
?例如,一个字符串到UUID的转换器。我想在Converter
中显示canonical 36-character hex string,并向另一个方向parse that string back into a UUID展示。
TextField
我看到Binder.BindingBuilder
提供了一对方法// String to UUID
UUID uuid = UUID.fromString( myString ) ;
// UUID to String
String myString = uuid.toString() ;
,它们都带有一对withConverter
对象。
SerializableFunction
withConverter
Binder.BindingBuilder::
(SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation)
withConverter
Binder.BindingBuilder::
➥那么,如何定义一对SerializableFunction
对象/类?
我注意到该接口列出了一个已知的子接口ValueProvider
(SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation, String errorMessage)
。看起来很熟悉,我直觉这是轻松定义简短的简单转换器的关键。但是我不太了解lambdas的语法,以及这里发生的所有事情。
我不是在询问如何编写实现Converter
的类。我在问如何编写一对SerializableFunction
参数以作为项目符号项传递到上面列出的Binder.BindingBuilder::withConverter
方法中。
引用that JavaDoc:
<SOURCE,TARGET>
...
Interface Binder.BindingBuilder<BEAN,TARGET>
withConverter
使用映射函数和可能的异常作为错误消息,将绑定映射到另一种数据类型。
映射函数用于在表示类型(必须与绑定的当前目标数据类型匹配)和模型类型(可以是任何数据类型,并成为绑定的新目标类型)之间进行转换。调用
default <NEWTARGET> Binder.BindingBuilder<BEAN,NEWTARGET> withConverter(SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation)
时,绑定的目标类型必须与getter / setter类型匹配。例如,可以使用诸如
之类的适当函数将TextField绑定到整数类型的属性。bind(ValueProvider, Setter)
类型参数:
withConverter(Integer::valueOf, String::valueOf);
-转换为的类型参数:
NEWTARGET
-可以从旧目标类型转换为新目标类型的功能
toModel
-可以从新目标类型转换为旧目标类型的功能返回:
具有适当类型的新绑定
投掷:
toPresentation
-如果已经调用了绑定
答案 0 :(得分:4)
您可以通过将两个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(/* ... */);
答案 1 :(得分:0)
如果您多次需要转换器,建议您创建一个单独的类来实现接口com.vaadin.data.Converter
。但是,正如您已经知道的那样,也可以使用lambda(请参阅@ollitietavainen的答案)。但这不是Vaadin专用的,它是Java 8+功能,您可以阅读有关e.g. here的信息。基本上,只要需要使用一种方法实现接口的对象,就可以使用lambda。