Data binding 通过定义一对SerializableFunction对象,为数据绑定提供转换器

Data binding 通过定义一对SerializableFunction对象,为数据绑定提供转换器,data-binding,vaadin,vaadin8,vaadin10,vaadin-flow,Data Binding,Vaadin,Vaadin8,Vaadin10,Vaadin Flow,在vaadin8框架和vaadin10流中,数据绑定功能允许我们提供一个中介,在小部件的预期数据类型(例如String(对于TextField)和支持bean属性的数据类型(例如Integernumber)之间进行中介 在本例中,使用内置的转换器实现 但是为其他类型定义转换器如何?如何轻松定义一个简短的转换器?例如,字符串到-转换器。我想在文本字段中显示,并向另一个方向显示 我看到它提供了一对方法withConverter,这两个方法都接受一对SerializableFunction对象 Bi

在vaadin8框架和vaadin10流中,数据绑定功能允许我们提供一个中介,在小部件的预期数据类型(例如
String
(对于
TextField
)和支持bean属性的数据类型(例如
Integer
number)之间进行中介

在本例中,使用内置的
转换器
实现

但是为其他类型定义
转换器如何?如何轻松定义一个简短的
转换器
?例如,字符串到-转换器。我想在
文本字段中显示,并向另一个方向显示

我看到它提供了一对方法
withConverter
,这两个方法都接受一对
SerializableFunction
对象

  • Binder.BindingBuilder::
    (SerializableFunction-toModel,SerializableFunction-toPresentation)
  • Binder.BindingBuilder::
    (SerializableFunction-toModel,SerializableFunction-toPresentation,String-errorMessage)
➥ 那么如何定义对象/类对呢

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

我不是问如何编写一个实现类。我问的是如何编写这对参数,作为项目符号项传递给上面列出的方法

引述:

Interface Binder.BindingBuilder

带转换器

default Binder.BindingBuilder with converter(SerializableFunction to model,SerializableFunction to presentation)

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

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

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

类型参数:

NEWTARGET
-要转换为的类型

参数:

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

toPresentation
-可从新目标类型转换为旧目标类型的功能

返回:

具有适当类型的新绑定

抛出:

非法状态异常
-如果已调用bind


您可以通过将两个lambda表达式传递给带有转换器的
,如下所示:

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(/* ... */);

您可以通过将两个lambda表达式传递给带有转换器的
,如下所示:

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(/* ... */);

如果多次需要转换器,我建议创建一个单独的类来实现接口
com.vaadin.data.converter
。然而,正如您已经知道的,使用lambdas也是可能的(请参阅@ollitietavainen的答案)。但这不是Vaadin特有的,这是一个Java8+特性,您可以阅读。基本上,只要一个对象只需要一个方法来实现接口,就可以使用lambda。

如果多次需要转换器,我建议创建一个单独的类来实现接口
com.vaadin.data.converter
。然而,正如您已经知道的,使用lambdas也是可能的(请参阅@ollitietavainen的答案)。但这不是Vaadin特有的,这是一个Java8+特性,您可以阅读。基本上,你可以使用lambdas,只要一个对象实现一个接口,只需要一个方法。

你是在问如何制作你自己的自定义转换器吗?@Jay Nope。我不是问如何编写一个实现类。我问的是如何编写一对
SerializableFunction
参数来传递给问题中作为项目符号项列出的方法。检查我在前一句中链接的JavaDoc。你是在问如何制作自己的自定义转换器吗?@Jay Nope。我不是问如何编写一个实现类。我问的是如何编写一对
SerializableFunction
参数来传递给问题中作为项目符号项列出的方法。检查我在前一句中链接的JavaDoc。常规Lambda如何符合
.withConverter
方法的要求?这是因为Java 8 magic-和SerializableFunction接口上的
@functionInterface
注释。查看javadocs了解更多信息:这确实有效;在我的项目中验证。但我还是很困惑。如果我们可以插入一个普通的Lambda,那么Vaadin团队定义
SerializableFunction
接口的目的是什么?我意识到我之前评论中提出的问题本身就是一个有趣的话题。因此,我提出了一个单独的问题,常规Lambda如何符合
.withConverter
方法的要求?这是因为Java 8 magic和SerializableFunction接口上的
@functionInterface
注释。查看javadocs了解更多信息:这确实有效;在我的项目中验证。但我还是很困惑。Va的目的是什么