基础
数据绑定链接UI
元素和模型,以便用户可以编辑或查看模型中的数据。例如,将文本Text
链接到模型对象(比如Person
)的String name
属性:
- 将模型属性的当前值复制到文本小部件用以渲染。
- 向
UI
元素和模型对象注册侦听器以同步或持久化数据。
使用数据绑定框架data binding
可以很方便的实现监听器,并提供一个通用的轮子来进行数据验证和转换。它可以轻松地将数据源链接到文本字段、下拉列表、表格和树,用于查看和编辑。在实际应用场景中,一侧的更改并不总是立即传播到另一侧, 数据绑定框架涵盖了这些更高级且实用的内容。
简单的例子
图 1 描述了两个UI
对象的简单绑定。在这种情况下,模型和目标对象都是文本。两个小部件的绑定是通过调用bind
来完成的. 通过上下文调用bind
方法实现绑定。界面上的Model
的值首先被复制到Target
。然后,data binding
将监听Target
及Model
上的更改,并传播变化以保持双方数值一致, 实现双向绑定。
图1
设计目标
- 便于使用
- 使默认情况变得简单:例如,文本小部件的简单绑定应该是一行代码。
- 不应需要新的或自定义的控件,或现有控件的包装:单独创建小部件。理想情况下,创建小部件的代码保持完全相同,只有初始值的设置和侦听器的注册被对数据绑定框架的调用所取代。
- 启用生命周期管理:例如,处置
SWT
组合应取消注册用于绑定该组合中的控件的所有侦听器和其他帮助程序对象。
- 可定制
- 将绑定代码与创建小部件的代码分开:这允许用户以任何他们想要的方式创建小部件,包括使用可视化编辑器。
- 支持可插入验证器和转换器(但提供默认值):例如,为整数和浮点数提供默认转换器(格式化程序)和验证器。
- 允许绑定到对象或控件的不同方面:例如,绑定到控件的启用状态而不是其值,或者在微调器的情况下小部件,绑定到当前选择、最小值和最大值。
- 易于扩展
- 用于支持新的或自定义的控件
- 用于支持其他数据源
基本思想
绑定意味着目标对象和原始对象的值要保持同步(见图 2)。分别称为target和model。在绑定时, 模型的当前状态被复制到目标。之后,更新两者目标可更新和模型可更新将被传播到另一个可更新。绑定活动是监听目标上的变化和模型可更新,并利用转换器和验证器来传播这些变化。
图2
例如,要将SWT
文本小部件的txtName 绑定到包含名为name
属性的模型对象mPerson, 代码实现如下:
IUpdatable target = dataBindingContext.createUpdatable(txtName);
IUpdatable model = dataBindingContext.createUpdatable(new PropertyDescription(mPerson, "name"));
dataBindingContext.bind(target,model,null);
可更新对象是使用工厂方法从PropertyDescription
创建的。 描述对象由创建可更新的工厂解释对象,数据绑定框架不会对它们强加任何语义。 IUpdatableFactory
的实现者指定哪些描述对象可以创建可更新的对象。
数据绑定上下文提供了在直接绑定到模型属性的方法,因此上面的示例可以归结为只有一行代码:
dataBindingContext.bind(txtName, new PropertyDescription(mPerson, "name"), null);
bind
方法的第三个参数是一个可选的绑定规范对象,可以指定一个自定义验证器或转换器。
绑定始终在数据绑定上下文内执行。对于可更新对象, 上下文定义了一个共同的生命周期(比如disposing
)。也可以对上下文中的所有绑定进行绑定策略选择,例如是否验证, 更新是否自动执行。最后就可以注册了用于使用数据创建可更新对象、验证器和转换器的工厂绑定上下文。这就是数据绑定框架可扩展的原因。
可以直接在可更新对象的(较低)级别上创建绑定,或者在(更高)级别的描述对象上。
数据绑定详细信息
本节详细解释数据绑定框架的主要方面。
数据绑定
DataBinding
类包含许多静态方法,用于创建和设置数据绑定上下文。创建数据绑定上下文时, 为其提供用于创建可更新对象的工厂很重要且常用。一般情况下, 绑定的生命周期与组件保持一致, 比如SWT
控件、JFace Viewer
和POJO
模型对象,如下提供了便捷的方法:
public static IDataBindingContext createContext(Control control);
数据绑定上下文
绑定是在数据绑定上下文中执行的。注册工厂 使用数据绑定上下文确定它如何创建可更新对象 描述对象,以及当没有时使用哪些转换器和验证器 给出了特定的转换器或验证器。
更新值
可更新值是保存单个值的可更新对象。一个可更新的值可以绑定到另一个可更新的值。 绑定目标和模型值首先设置目标的当前值为模型的当前值,从那时起,跟踪两者的变化 目标和模型,每当任何一方进行更改时, 此更改将在另一侧执行。
当绑定两个不同类型的可更新值时需要通过getValueType()
方法来特别指明返回类型。用户可以显式提供转换器,或使用数据提供的默认转换器绑定上下文。
更新集合
可更新集合包含元素的集合。它可以通知监听器关于细粒度的变化,如元素的添加和删除,以及元素内的变化。
转换器和验证器
有时,数据需要验证。在最简单的情况下,并非所有 String 值都可以解析为int
、float
或 Date
,因此对字符串值的任何更改都需要在转换之前进行验证。 验证的结果是一条错误消息。要在 UI 中显示此消息,可以使用数据绑定,因为 DatabindingService.getValidationMessage()
返回包含字符串的可更新值:
databindingService.bind(validationErrorTextWidget, “text”, databindingService.getValidationMessage());
更新和验证政策
在数据绑定上下文的级别上,更新可以在收到变更事件(POLICY_AUTOMATIC
)时发生,也可在调用显式方法(POLICY_EXPLICIT
)时再被触发。
SWTUpdatableFactory
支持不同的更新策略:TIME_EARLY
(每次按键)、TIME_LATE
(失去焦点时)和 TIME_NEVER
(未触发变更事件)。