0

在 Vaadin 8 Framework 和 Vaadin 10 Flow 中,数据绑定功能让我们可以提供 aConverter在小部件的预期数据类型(例如Stringfor a TextField)和支持 bean 属性的数据类型(例如Integernumber)之间进行调解。

在此示例中,使用了内置Converter实现StringToIntegerConverter

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

但是Converter为其他类型定义一个呢?我怎样才能轻松地定义一个短而甜的Converter?例如,字符串到UUID的转换器。我想在a中显示规范的 36 个字符的十六进制字符串TextField,然后从另一个方向将该字符串解析回 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)
  • Binder.BindingBuilder::withConverter(SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation, String errorMessage)

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

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

不是在问如何编写一个实现Converter. 我在问如何编写一对参数以作为项目符号SerializableFunction传递给上面列出的方法。Binder.BindingBuilder::withConverter

引用该 JavaDoc

Interface Binder.BindingBuilder<BEAN,TARGET>

…</p>

withConverter

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

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

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

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

类型参数:

NEWTARGET- 要转换为的类型

参数:

toModel- 可以将旧目标类型转换为新目标类型的功能

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

回报:

具有适当类型的新绑定

抛出:

IllegalStateException- 如果绑定已经被调用

4

2 回答 2

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(/* ... */);
于 2018-07-12T09:58:14.673 回答
0

如果您多次需要转换器,我建议创建一个单独的类实现接口com.vaadin.data.Converter。但是,正如您已经知道的那样,使用 lambdas 也是可能的(请参阅@ollitietavainen 的答案)。但这不是 Vaadin 特有的,它是一个 Java 8+ 功能,您可以在此处了解相关信息。基本上,您可以在任何需要实现接口的对象只使用一种方法的地方使用 lambda。

于 2018-07-12T10:58:24.743 回答