ZK實際應用:MVVM –與ZK客戶端API一起使用

在之前的文章中,我們使用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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372127.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372127.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372127.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RPC框架Dubbo分析

1&#xff0c;背景隨著互聯網的發展&#xff0c;網站應用的規模不斷擴大&#xff0c;常規的垂直應用架構已無法應對&#xff0c;分布式服務架構以及流動計算架構勢在必行&#xff0c;亟需一個治理系統確保架構有條不紊的演進單一應用架構當網站流量很小時&#xff0c;只需一個應…

定時器、計時器。

//第一種 每一秒執行一次&#xff08;重復性&#xff09;double delayInSeconds 1.0;timer dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));dispatch_source_set_timer(timer, DISPATCH_TIME_NO…

mybatis oracle trim,Mybatis trim標簽

trim代替where/set標簽trim是更靈活用來去處多余關鍵字的標簽&#xff0c;它可以用來實現where和set的效果。SELECT *FROM user uu.username LIKE CONCAT(CONCAT(%, #{username, jdbcTypeVARCHAR}),%)AND u.sex #{sex, jdbcTypeINTEGER}AND u.birthday #{birthday, jdbcTypeD…

自己初學時的隨筆記錄

如果富文本編輯器 jsp....文件可以找到但是就是顯示不出來&#xff0c;可能是Controller控制器中RequestMapping后邊沒有寫路徑 ---------------------------------------------------------------------------------------------------------------------------- iframe框架內…

終極JPA查詢和技巧列表–第1部分

我們可以在Internet上找到一些JPA“如何做”&#xff0c;在本博客的此處&#xff0c;教您如何使用JPA執行多項任務。 通常&#xff0c;我看到有人問有關使用JPA進行查詢的問題。 通常&#xff0c;為了回答此類問題&#xff0c;提供了幾個鏈接&#xff0c;以嘗試找到該問題的解決…

請求重定向(網上抄錄)

抄錄地址 http://www.sosuo8.com/article/show.asp?id1158 (1)Server.Transfer方法: Server.Transfer("m2.aspx");//頁面轉向(服務器上執行). 服務器停止解析本頁,保存此頁轉向前的數據后,再使頁面轉向到m2.aspx, 并將轉向前數據加上m2.aspx頁結果返回給瀏覽器. (…

oracle走當前時間分區,Oracle分區使用波斯日歷的時間間隔

與數據庫級NLS_CALENDAR相比&#xff0c;沒有其他方法可以在不同的日歷中定義間隔。通過使用虛擬列劃分每個日期落入的(波斯)月份的數字表示&#xff0c;可以得到相同的效果&#xff1a;create table test_temp_times (id number(18) not null,xdate date not null,str varchar…

Spring集成–第2節–更多世界

這是Spring Integration Session 1的后續活動 第一部分是使用Spring Integration的簡單Hello World應用程序。 我想通過考慮其他一些方案來進一步介紹它。 因此&#xff0c;對Hello World應用程序的第一個更改是添加網關組件。 要快速重新訪問較早的測試程序&#xff0c;請執行…

Python中Dict的查找

Dict的類型的查找使用的是lookdict函數 static PyDictKeyEntry * lookdict(PyDictObject *mp, PyObject *key,Py_hash_t hash, PyObject ***value_addr) 函數的參數中&#xff0c;*value_addr是指向匹配slot中值的指針。 這個函數在正確的情況下一定會返回一個指向slot的指針&a…

文字特效代碼大全

代碼收集來源于網絡博友,感謝博友提供,本人只收集,整理,說明. 1.刪除線:<FONT style"TEXT-DECORATION: line-through">寫上你想寫的字</FONT> 效果如下 寫上你想寫的字 2.文字頂部加橫線:<font style"text-decoration:overline">寫上你想…

oracle 會話實例,返璞歸真:Oracle實例級別和會話級別的參數設置辨析

楊廷琨(yangtingkun)云和恩墨 CTO高級咨詢顧問&#xff0c;Oracle ACE 總監&#xff0c;ITPUB Oracle 數據庫管理版版主參數文件是Oracle數據庫文件中級別最低&#xff0c;也是最基本的文件&#xff0c;但是也是數據庫實例啟動第一個涉及的文件。如果參數文件缺失或者某些參數設…

ExtJs CheckboxSelectionModel 全選操作后 清空表格頭的checkBox

關鍵代碼&#xff1a; var hd Ext.getCmp("interviewSubscriptionGrid").getEl().select(div.x-grid3-hd-checker).first(); if (hd.hasClass(x-grid3-hd-checker-on)) { hd.removeClass(x-grid3-hd-checker-on); } 轉自&#xff1a;ExtJs Checkbox…

在多節點集群中運行Cassandra

這篇文章收集了我在多節點中設置Apache Cassandra集群的步驟。 在設置集群時&#xff0c;我已經參考了Cassandra Wiki和Datastax文檔。 詳細介紹了以下過程&#xff0c;分享了我建立群集的經驗。 設置第一個節點 添加其他節點 監視集群– nodetool &#xff0c; jConsole &am…

Oracle 添加 scott 示例用戶

學習SQL有一段時間了&#xff0c;但是也忘記的差不多了&#xff0c;今天有趕緊復習復習&#xff0c;然后發現一個問題&#xff0c;為啥之前看的視頻教程&#xff0c;馬士兵用的Oracle有scott用戶和那些表格&#xff0c;而我的沒有&#xff1f;難道是Oracle取消了&#xff1f;然…

win8oracle10g安裝報錯,Win8電腦安裝Oracle 10g提示程序異常終止的解決方法

有win8系統用戶反映說在安裝Oracle 10g的時候&#xff0c;選擇高級安裝之后&#xff0c;就彈出一個窗口&#xff0c;提示程序異常終止&#xff0c;發生內部錯誤&#xff0c;導致Oracle 10g安裝失敗&#xff0c;該怎么解決這樣的問題呢&#xff1f;下面隨小編一起來看看Win8電腦…

MFC的消息循環

MFC的消息循環 消息分為隊列消息(進入線程的消息隊列)和非隊列消息(不進入線程的消息隊列)。對于隊列消息&#xff0c;最常見的是鼠標和鍵盤觸發的消息&#xff0c;例如WM_MOUSERMOVE,WM_CHAR等消息&#xff1b;還有例如&#xff1a;WM_PAINT、WM_TIMER和WM_QUIT。當鼠標、鍵…

<avatar: frontiers of pandora>技術overview

https://www.eurogamer.net/digitalfoundry-2023-avatar-frontiers-of-pandora-and-snowdrop-the-big-developer-tech-interview https://www.youtube.com/watch?vLRI_qgVSwMY&t394s 主要來自euro gamer上digital foundry對于avatar的開發團隊Massive工作室的采訪&#xf…

使用Hibernate 4,JPA和Maven的架構創建腳本

這種情況很簡單–您想要在構建應用程序時生成數據庫模式創建腳本&#xff08;然后在目標數據庫上執行腳本&#xff09;&#xff0c;這對于Hibernate 3來說相對容易&#xff0c;因為有 hibernate3-maven-plugin &#xff0c;但是與Hibernate 4不兼容。當然&#xff0c;對于每個新…

iOS 啟動連續閃退保護方案

版權聲明&#xff1a;本文由劉笑江原創文章&#xff0c;轉載請注明出處: 文章原文鏈接&#xff1a;https://www.qcloud.com/community/article/79 來源&#xff1a;騰云閣 https://www.qcloud.com/community 一.引言 “如果某個實體表現出以下任何一種特性&#xff0c;它就具備…

實戰Java內存泄漏問題分析 -- hazelcast2.0.3使用時內存泄漏 -- 2

hazelcast 提供了3中方法調用startCleanup:第一種是在ConcuurentMapManager的構造函數中&#xff0c;通過調用node的executorManager中的ScheduledExecutorService來創建每秒運行一次cleanup操作的線程&#xff08;代碼例如以下&#xff09;。因為這是ConcuurentMapManager構造…