mvvm 后端_ZK实际应用:MVVM –与ZK客户端API一起使用

mvvm 后端

在以前的文章中,我们已经使用ZK的MVVM实现了以下功能:
  • 将数据加载到表中
  • 使用表单绑定保存数据
  • 删除条目并以编程方式更新视图

ZK MVVM和ZK MVC实现方式之间的主要区别是,我们不直接在controller(ViewModel)类中访问和操作UI组件。 在本文中,我们将看到如何将某些UI操作委派给客户端代码,以及如何将参数从View传递到ViewModel。

目的

为我们的简单清单CRUD功能构建更新功能。 用户可以在表中就地编辑条目,并可以选择更新或放弃所做的更改。 修改后的条目以红色突出显示。

ZK实战功能

  • ZK客户端API
  • ZK风格班
  • MVVM:将参数从视图传递到ViewModel

分步实施  

在列表框中启用就地编辑,这样我们就可以编辑条目:

<listcell><textbox inplace="true" value="@load(each.name)" ...</textbox></listcell>....<listcell><doublebox inplace="true" value="@load(each.price)" ...</textbox></listcell>...
  • inplace =” true”呈现输入元素,例如Textbox,但其边框未显示为纯标签; 仅当选择输入元素时才显示边框
  • 第2、6行,“每个”指的是数据收集中的每个Item对象

编辑条目后,我们希望为用户提供更新或放弃更改的选项。
仅当用户对列表框条目进行了修改时,“更新”和“放弃”按钮才需要可见。 首先,我们定义JavaScript函数以显示和隐藏“更新”和“放弃”按钮:

<toolbar>...<span id="edit_btns" visible="false" ...><toolbarbutton label="Update" .../><toolbarbutton label="Discard" .../></span>
</toolbar><script type="text/javascript">function hideEditBtns(){jq('$edit_btns').hide();}function showEditBtns(){ jq('$edit_btns').show();}</script>...
  • 第2行,我们包装了Update and Discard ,并将可见性设置为false
  • 第9、13行中,我们定义了分别隐藏和显示“ 更新”和“ 放弃”按钮的函数
  • 第11、15行,我们使用jQuery选择器jq('$ edit_btns')检索ID为“ edit_btns”的ZK小部件; 请注意,ZK小部件ID的选择器模式为“ $”,而不是“#”

修改列表框中的条目后,我们将使“更新/丢弃”按钮可见,并使修改后的值变为红色。 单击“更新”或“放弃”按钮后,我们想再次隐藏按钮

由于这是纯UI交互,因此我们将使用ZK的客户端API:

<style>.inputs { font-weight: 600; }.modified { color: red; }
</style>
...<toolbar xmlns:w="client" >...<span id="edit_btns" visible="false" ...><toolbarbutton label="Update" w:onClick="hideEditBtns()" .../><toolbarbutton label="Discard" w:onClick="hideEditBtns()" .../></span></toolbar><script type="text/javascript">//show hide functionszk.afterMount(function(){jq('.inputs').change(function(){showEditBtns();$(this).addClass('modified');})});</script>...<listcell><doublebox inplace="true" sclass="inputs" value="@load(each.price)" ...</textbox></listcell>...
  • 第2行,我们为输入元素(文本框,Intbox,Doublebox,日期框)指定样式类,并将其分配给输入元素的sclass属性,例如。 第26行; sclass为ZK小部件定义样式类
  • 在第18〜20行,我们通过匹配所有输入元素的sclass名称来获取所有输入元素,并分配一个onChange事件处理程序。 更改输入元素中的值后,“更新/丢弃”按钮将变为可见,并且修改后的值将以红色突出显示。
  • 第17行,在创建ZK小部件时运行zk.afterMount
  • 第6行,我们指定了客户端名称空间,以便我们可以使用语法“ w:onClick”注册客户端onClick事件侦听器。 请注意,我们仍然可以注册通常在服务器上同时处理的onClick事件侦听器。
  • 第9、10行,我们为客户端分配了onClick事件监听器; hideEditBtns函数将被调用以使按钮再次不可见

定义一种将修改后的Item对象存储到集合中的方法,以便如果用户选择这样做,则可以批量更新更改:

public class InventoryVM {private HashSet<Item> itemsToUpdate = new HashSet<item>();...@Commandpublic void addToUpdate(@BindingParam("entry") Item item){itemsToUpdate.add(item);}
  • 第6行,我们将此方法注释为命令方法,以便可以从View调用它
  • 第7行, @ BindingParam(“ entry”)项目项绑定了一个名为“ entry”的任意命名的参数; 我们预计参数将为Item类型

创建一种方法来更新在视图中对数据模型所做的更改

public class InventoryVM {private List<Item> items;private HashSet<Item> itemsToUpdate = new HashSet<item>();...@NotifyChange("items")@Commandpublic void updateItems() throws Exception{for (Item i : itemsToUpdate){i.setDatemod(new Date());DataService.getInstance().updateItem(i);}itemsToUpdate.clear();items = getItems();}

对列表框条目进行修改后,请调用addToUpdate方法,并将经过编辑的Item对象传递给该方法,该对象又被保存到itemsToUpdate集合中。

<listitem><listcell><doublebox value="@load(each.price) @save(each.name, before='updateItems')"  onChange="@command('addToUpdate',entry=each)" /></listcell>...
</listitem>
  • @save(each.name,before ='updateItems')确保除非调用updateItems(即,当用户单击“更新”按钮时),否则不保存修改后的值。

最后,当用户单击更新时,我们调用updateItems方法来更新对数据模型的更改。 如果单击“丢弃”,我们将调用getItems刷新列表框,而不进行任何更改

...<toolbarbutton label="Update" onClick="@command('updateItems')" .../><toolbarbutton label="Discard" onClick="@command('getItems')" .../>...

简而言之

  • 在MVVM模式下,我们努力使ViewModel代码独立于任何View组件
  • 由于我们没有直接引用ViewModel代码中的UI组件,因此可以使用ZK的客户端API将UI操作(在示例代码中,显示/隐藏,样式更改)代码委托给客户端
  • 我们可以在ZK客户端使用jQuery选择器和API
  • 我们可以使用@BindingParam轻松地将参数从View传递到ViewModel

接下来,在处理MVVM验证器和转换器之前,我们将详细介绍ZK样式。  

ViewModel(ZK在执行中[0]〜[3]):

public class InventoryVM {private List<Item> items;private Item newItem;private Item selected;private HashSet<Item> itemsToUpdate = new HashSet<Item>();public InventoryVM(){}//CREATE@NotifyChange("newItem")@Commandpublic void createNewItem(){newItem = new Item("", "",0, 0,new Date());}@NotifyChange({"newItem","items"})@Commandpublic void saveItem() throws Exception{DataService.getInstance().saveItem(newItem);newItem = null;items = getItems();}@NotifyChange("newItem")@Commandpublic void cancelSave() throws Exception{newItem = null;}//READ@NotifyChange("items")@Commandpublic List<Item> getItems() throws Exception{items = DataService.getInstance().getAllItems();for (Item j : items){System.out.println(j.getModel());}Clients.evalJavaScript("zk.afterMount(function(){jq('.inputs').removeClass('modified').change(function(){$(this).addClass('modified');showEditBtns();})});"); //how does afterMount work in this case?return items;}//UPDATE@NotifyChange("items")@Commandpublic void updateItems() throws Exception{for (Item i : itemsToUpdate){i.setDatemod(new Date());DataService.getInstance().updateItem(i);}itemsToUpdate.clear();items = getItems();}@Commandpublic void addToUpdate(@BindingParam("entry") Item item){itemsToUpdate.add(item);}//DELETE@Commandpublic void deleteItem() throws Exception{if (selected != null){String str = "The item with name \""+selected.getName()+"\" and model \""+selected.getModel()+"\" will be deleted.";Messagebox.show(str,"Confirm Deletion", Messagebox.OK|Messagebox.CANCEL, Messagebox.QUESTION, new EventListener<Event>(){@Overridepublic void onEvent(Event event) throws Exception {if (event.getName().equals("onOK")){DataService.getInstance().deleteItem(selected);items = getItems();BindUtils.postNotifyChange(null, null, InventoryVM.this, "items");}}});} else {Messagebox.show("No Item was Selected");} }public Item getNewItem() {return newItem;}public void setNewItem(Item newItem) {this.newItem = newItem;}public Item getselected() {return selected;}public void setselected(Item selected) {this.selected = selected;}
}

视图(ZK处于操作状态[0]〜[3]):

<zk><style>.z-toolbarbutton-cnt { font-size: 17px;} .edit-btns {border: 2pxsolid #7EAAC6; padding: 6px 4px 10px 4px; border-radius: 6px;}.inputs { font-weight: 600; } .modified { color: red; }</style><script type="text/javascript">function hideEditBtns(){ jq('$edit_btns').hide(); }function showEditBtns(){ jq('$edit_btns').show(); }zk.afterMount(function(){ jq('.inputs').change(function(){$(this).addClass('modified'); showEditBtns(); }) });</script><window apply="org.zkoss.bind.BindComposer"viewModel="@id('vm') @init('lab.sphota.zk.ctrl.InventoryVM')"xmlns:w="client"><toolbar width="100%"><toolbarbutton label="Add"onClick="@command('createNewItem')" /><toolbarbutton label="Delete"onClick="@command('deleteItem')"disabled="@load(empty vm.selected)" /><span id="edit_btns" sclass="edit-btns" visible="false"><toolbarbutton label="Update" onClick="@command('updateItems')" w:onClick="hideEditBtns()"/><toolbarbutton label="Discard"onClick="@command('getItems')" w:onClick="hideEditBtns()" /></span></toolbar><groupbox mold="3d"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 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" mold="trendy"onClick="@command('saveItem')"  /><button width="80px" label="Cancel" mold="trendy"onClick="@command('cancelSave')" /></cell></row></rows></grid></groupbox><listbox selectedItem="@bind(vm.selected)" model="@load(vm.items) "><listhead><listheader label="Name" sort="auto" hflex="2" /><listheader label="Model" sort="auto" hflex="1" /><listheader label="Quantity" sort="auto" hflex="1" /><listheader label="Unit Price" sort="auto" hflex="1" /><listheader label="Last Modified" sort="auto" hflex="2" /></listhead><template name="model"><listitem><listcell><textbox inplace="true" width="110px" sclass="inputs"value="@load(each.name) @save(each.name, before='updateItems')"onChange="@command('addToUpdate',entry=each)"></textbox></listcell><listcell><textbox inplace="true" width="110px" sclass="inputs" value="@load(each.model) @save(each.model, before='updateItems')"onChange="@command('addToUpdate',entry=each)" /></listcell><listcell><intbox inplace="true" sclass="inputs" value="@load(each.qty) @save(each.qty, before='updateItems')"onChange="@command('addToUpdate',entry=each)" /></listcell><listcell><doublebox inplace="true" sclass="inputs" format="###,###.00" value="@load(each.price) @save(each.price, before='updateItems')"onChange="@command('addToUpdate',entry=each)" /></listcell><listcell label="@load(each.datemod)" /></listitem></template></listbox></window>
</zk>
  • ZK客户端参考
  • ZK开发人员参考:@BindingParam

参考: ZK in Action [3]:MVVM –与我们的JCG合作伙伴 Lance Lu的ZK Client API一起在Tech Dojo博客上工作。


翻译自: https://www.javacodegeeks.com/2012/07/zk-in-action-mvvm-working-together-with.html

mvvm 后端

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/354912.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信分享朋友圈固定缩略图 php,微信转发或分享朋友圈带缩略图、标题和描述的实现方法...

自己做博客以来&#xff0c;很早之前分享过文章至朋友圈&#xff0c;那个时候分享过去的文章自动获取页面的比例适合的图片为所缩略图&#xff1a;后期就很少分享至朋友圈&#xff0c; 近来分享文章给朋友后&#xff0c;发现不带缩略图和简介了&#xff0c;觉得这样很不好看&am…

java监控rabbitMq服务状态,SpringCloud-Turbine【RabbitMQ服务监控】

前面我们介绍了通过turbine直接聚合多个服务的监控信息&#xff0c;实现了服务的监控&#xff0c;但是这种方式有个不太好的地方就是turbine和服务的耦合性太强了&#xff0c;针对这个问题&#xff0c;我们可以将服务的监控消息发送到RabbitMQ中&#xff0c;然后turbine中Rabbi…

jpa 查询 列表_终极JPA查询和技巧列表–第1部分

jpa 查询 列表我们可以在Internet上找到一些JPA“如何做”&#xff0c;在本博客的此处&#xff0c;教您如何使用JPA执行多项任务。 通常&#xff0c;我看到有人问有关使用JPA进行查询的问题。 通常&#xff0c;为了回答此类问题&#xff0c;提供了几个链接以尝试找到该问题的解…

windows下php swoole扩展,Windows 下安装 swoole 图文教程(php)

Windows 下安装 swoole 具体步骤&#xff1a;Swoole,原本不支持在Windows下安装的&#xff0c;所以我们要安装Cygwin来使用。在安装Cygwin下遇到了很多坑&#xff0c;百度经验上的文档不是很全&#xff0c;所以我把自己安装Cygwin和Swoole写下来相当于对自己的沉淀吧。首先准备…

新CalendarFX视图:MonthGridView!

我和我的团队最近开始为CalendarFX创建新视图&#xff0c;其最初目标是在垂直列中显示整年。 该视图的名称是MonthGridView。 像往常一样&#xff0c;编码时目标略有变化。 该视图现在可以显示任意数量的月份&#xff0c;并且可以在前面或后面添加额外的月份。 现在&#xff0c…

php如何和c进行数据交换,PHP与 后台c交换数据 | 学步园

为什么要用json跟XML相比&#xff0c;JSON的优势在于格式简洁短小&#xff0c;特别是在处理大量复杂数据的时候&#xff0c;这个优势便显得非常突出。从各浏览器的支持来看&#xff0c;JSON解决了因不同浏览器对XML DOM解析方式不同而引起的问题。目前&#xff0c;JSON已经成为…

硒测试的干净架构

在这篇博客文章中&#xff0c;我想介绍一种具有最佳设计模式的Selenium测试的简洁架构&#xff1a;页面对象&#xff0c;页面元素&#xff08;通常称为HTML包装器&#xff09;和自行开发的非常小巧的框架。 该体系结构不限于示例中使用的Java&#xff0c;也可以以任何其他语言应…

ThinkPHP5 封装邮件发送服务(可发附件)

1、Composer 安装 phpmailer 1composer require phpmailer/phpmailer2、ThinkPHP 中封装邮件服务类 我把它封装在扩展目录 extend/Mail.php 文件里&#xff0c;内容如下&#xff1a; 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748…

密码学笔记——eval(function(p,a,c,k,e,d) 加密破解

密码学笔记——eval(function(p,a,c,k,e,d) 的加密破解 例题&#xff1a; 小明某天在看js的时候&#xff0c;突然看到了这么一段代码&#xff0c;发现怎么也理不出代码逻辑&#xff0c;你能帮帮他吗&#xff1f; 格式&#xff1a;SimCTF{} eval(function(p,a,c,k,e,d){efunctio…

Windows负载机JVM 远程监控Linux服务器下tomcat

基本是跟着网上的操作进行的&#xff0c;除了遇到一个Local host name unknown的问题&#xff1a; 一、Linux服务器操作部分 服务器地址&#xff1a;10.64.111.68 首先配置JMX&#xff1a; 1.找到jdk目录 [rootC68 demo]# echo $JAVA_HOME /root/demo/jdk1.8.0_60 2. cd 到/roo…

二维码支付原理分析及安全性的探究

“二维码支付”安全么&#xff1f; 1 引言 随时支付宝和微信的线下不断推广&#xff0c;目前使用手机进行二维码支付已经逐渐成为一种时尚了。 但是大家有没有思考过&#xff1a;这种便捷的支付方式到底安不安全呢&#xff1f;今天我们就针对这个话题来进行一些探讨吧。 2 …

混合高斯模型(Mixtures of Gaussians)和EM算法

混合高斯模型&#xff08;Mixtures of Gaussians&#xff09;和EM算法 这篇讨论使用期望最大化算法&#xff08;Expectation-Maximization&#xff09;来进行密度估计&#xff08;density estimation&#xff09;。 与k-means一样&#xff0c;给定的训练样本是&#xff0c;我们…

wordpress archive.php,wordpress分类目录模板(archive.php)制作

本课程视频是VIP会员课程&#xff0c;学习请进入VIP学习区。分类目录模板通常包括二种&#xff0c;一种是普通文章列表目录&#xff0c;一种是产品图片展示列表目录。文章列表目录是通过将分类下的文章标题通过无序列表的形式展示出来。如下图。产品图片列表目录是将产品的第一…

linux c统计进程网络读写,linux网络分析、性能分析、文本格式化、文件读写操作之利器(mtr、top、jq、sponge)...

好的工具能够让我们工作更加高效&#xff0c;结合工作中的情况&#xff0c;今天分享下linux下比较好用的几个工具。网络分析工具mtrmtr是网络链路检测判断问题非常好用的工具&#xff0c;集成了tracert和ping这两个命令的功能&#xff0c;动态的输出检测结果。mtr 默认发送icmp…

C++入门经典-例2.13-左移运算

1&#xff1a;代码如下&#xff1a; // 2.13.cpp : 定义控制台应用程序的入口点。 //#include "stdafx.h" #include<iostream> using namespace std; void main() {int a0x40,b;ba<<1;//左移1位cout << b << endl;//以十进制输出 } View Cod…

jwebsocket传图片_Java中带有JWebSocket的WebServerSocket

jwebsocket传图片首先&#xff0c;转到http://jwebsocket.org/下载2个软件包Server and Client。 如果要查看源代码&#xff0c;请下载源代码包。 服务器 解压缩服务器程序包。 转到“ conf”文件夹 选择“ jWebSocket.xml”文件打开 编辑“ jWebSocket.xml”文件&#xff…

linux xargs命令,xargs 命令教程

xargs是 Unix 系统的一个很有用的命令&#xff0c;但是常常被忽视&#xff0c;很多人不了解它的用法。本文介绍如何使用这个命令。一、标准输入与管道命令Unix 命令都带有参数&#xff0c;有些命令可以接受"标准输入"(stdin)作为参数。$ cat /etc/passwd | grep root…

java 职责链模式_Java中的责任链模式

java 职责链模式当应有几个处理器来执行某项操作并为这些处理器定义特定顺序时&#xff0c;就需要采用责任链设计模式。 在运行时处理器顺序的可变性也很重要。模式的UML表示如下&#xff1a; 处理程序定义处理器对象的一般结构。 这里的“ HandleRequest”是抽象处理器方法。 …

ArcMap 导入Excel坐标数据

1 准备Excel坐标数据集合 2 ArcMap加入Excel数据 将excel文件放入arcmap工作区的物理路径下在工作区的根图层上点键&#xff0c;选择添加数据&#xff0c;找到excel文件并选择相应的工作薄完成后&#xff0c;excel工作薄即导入工作区左边的图层下。3 ArcMap加入图层文件 在S…

linux6如何分区,CentOS6.9安装 硬盘分区方案与分区步骤

Linux默认可分为3个分区&#xff0c;分别是boot分区、swap分区和根分区&#xff1a;1、swap&#xff1a;交换分区&#xff0c;实现虚拟内存&#xff0c;建议大小是物理内存的1~2倍。2、/boot&#xff1a;用来存放与系统启动有关的程序&#xff0c;比如启动引导装载程序等&#…