这是我们从头开始构建ZK应用程序的第二集。
上一篇文章涉及使用MVVM将数据加载和呈现到表中。
在本文中,我们将向您介绍ZK MVVM的表单绑定。
目的
我们将构建一个“添加”功能,使我们能够将新条目保存到清单中。
![]() |
单击“添加”时出现表格 |
![]() |
单击“保存”后,将添加新条目 |
ZK实战功能
- MVVM:保存,表单绑定,条件绑定
使用MVVM表单绑定添加新条目
我们需要实现以下部分:
- 增强我们的ViewModel POJO
- 添加UI标记以呈现表单并用适当的注释装饰标记
ViewModel类
public class InventoryVM {
private List<item> items;
private Item newItem;
@NotifyChange("newItem")
@Command
public void createNewItem(){
newItem = new Item("", "",0, 0,new Date());
}
@NotifyChange({"newItem","items"})
@Command
public void saveItem() throws Exception{
DataService.getInstance().saveItem(newItem);
newItem = null;
items = getItems();
}
@NotifyChange("newItem")
@Command
public void cancelSave() throws Exception{
newItem = null;
}
public List<item> getItems() throws Exception{
items = DataService.getInstance().getAllItems();
return items;
}
}
- 第4行,我们声明了一个名为newItem的Item对象,该对象将引用要保存到数据库的Item实例。
- 第6行, @ NotifyChange通知绑定程序在关联的ViewModel属性状态上更新UI。
在下面显示的UI标记的第8行,我们有一个Groupbox并带有visible =” @ load( 不是空vm.newItem ) 批注 ,因此一旦createNewItem将Item实例分配给newItem时 ,Groupbox将变为可见。
简而言之, @ NotifyChange会根据ViewModel属性的更新来刷新UI。 - 在第7行,我们用@Command注释了createNewItem方法,在下面显示的UI标记中,在第4行,我们有一个带有onClick =” @ commnad(createNewItem)”的工具栏按钮 。 因此,当单击工具栏按钮时,将调用createNewItem方法。
- 类似地,从第12行到第18行,我们有一个saveItem方法,当其对应的onClick事件被触发时将调用该方法。 将新的Item对象保存到数据库缓存后,我们将newItem重置为null并检索新的项目列表。 与之前一样,使用@NotifyChange对ViewModel属性newItem (现在再次为null)和项目 (现在具有额外的条目)所做的更改将反映到UI。
标记
<window apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('lab.sphota.zk.ctrl.InventoryVM')">
<toolbar>
<toolbarbutton label="Add" onClick="@command('createNewItem')" />
</toolbar>
<groupbox form="@id('itm') @load(vm.newItem)
@save(vm.newItem, before='saveItem')"
visible="@load(not empty vm.newItem)">
<caption label="New Item"></caption>
<grid width="50%">
<rows>
<row>
<label value="Item Name" width="100px"></label>
<textbox id="name" value="@bind(itm.name)" />
</row>
<row>
<label value="Model" width="100px"></label>
<textbox value="@bind(itm.model)" />
</row>
<row>
<label value="Unit Price" width="100px"></label>
<decimalbox value="@bind(itm.price)" format="#,###.00"
constraint="no empty, no negative" />
</row>
<row>
<label value="Quantity" width="100px"></label>
<spinner value="@bind(itm.qty)"
constraint="no empty,min 0 max 999:
Quantity Must be Greater Than Zero" />
</row>
<row>
<cell colspan="2" align="center">
<button width="80px" label="Save"
onClick="@command('saveItem')" mold="trendy" />
<button width="80px" label="Cancel"
onClick="@command('cancelSave')" mold="trendy" />
</cell>
</row>
</rows>
</grid>
</groupbox>
<listbox>
...
</listbox>
</window>
- 第1行,我们应用ZK的BindComposer的默认实现。 它负责实例化我们的ViewModel和Binder实例。
- 第2行,我们提供了要实例化的ViewModel的完整类名,并为其提供了ID以供将来参考
- 在第4行中,我们将ViewModel的“命令方法” createNewItem分配为工具栏按钮的onClick事件处理程序。
- 第6行,使用ID“ itm”使整个Groupbox中均可引用ViewModel中的newItem属性。
- 第6,7行使用表单绑定,以避免将无效或不完整的数据保存到ViewModel属性,将表单中的条目保存到一个临时对象,直到调用命令方法saveItem 。
- 在第8行,我们显示了Groupbox,只有用户单击“ Add”按钮时,它才能输入新的Item条目; 依次调用createNewItem方法并为VM属性newItem分配具有默认值(空字符串和0s)的Item实例。
- 在第14、18、22、27行中,我们将Item属性与输入元素绑定在一起。 @bind实际上等效于@load加@save。
简而言之
总结点形式:
- 使用表单绑定可避免通过将表单条目保存到临时对象来直接修改ViewModel属性中的数据。 仅在满足指定条件的情况下,才将数据写入ViewModel属性。 在我们的示例中,仅当调用saveItem方法时。
- @Command批注允许绑定程序将UI事件处理程序映射到ViewModel命令方法。
- @NotifyChange通知联编程序,在执行命令方法后,哪些ViewModel属性已被修改,以便可以将数据更改反映在UI上。
- 我们可以在运行时通过MVVM绑定将值分配给任何UI组件的属性,以操纵诸如可见性,样式,禁用/启用等参数。
在这篇文章中,我们还没有看到如何验证数据条目。 在此之前,我们将在下一篇文章中实现删除和编辑功能。
参考 ZK开发人员参考
参考: ZK in Action [1]:MVVM –来自我们JCG合作伙伴 Lance Lu的Form Binding ,位于Tech Dojo博客上。
翻译自: https://www.javacodegeeks.com/2012/07/zk-in-action-mvvm-form-binding.html