ZK 6中的MVVM初探
在上一篇文章中,我們已經看到Ajax框架ZK如何采用CSS選擇器啟發的Controller來在View中連接UI組件并監聽它們的事件。 在此ZK MVC模式下, View中的UI組件無需綁定到任何Controller方法或數據對象。 使用選擇器模式作為將View狀態和事件映射到Controller的靈活性,使代碼更適應更改。
MVVM在相反方向上實現關注點分離。 在這種模式下,視圖模型和綁定器機制代替了控制器。 綁定器將View的請求映射到View-Model中的動作邏輯,并更新雙方的任何值(數據),從而允許View-Model獨立于任何特定的View。
ZK 6中的MVVM的剖析
以下是ZK 6的MVVM模式的示意圖:
以下是圖中未傳達的一些其他要點:
BindComposer:
- 實現ZK的標準控制器接口(Composer&ComposerExt)
- 默認實現就足夠了,不需要修改
視圖:
- 通知活頁夾調用哪種方法以及在視圖模型上更新哪些屬性
視圖模型:
- 只是一個POJO
- 通過Java注釋與活頁夾進行通信
MVVM運行中
考慮在不知道確切的UI標記的情況下顯示簡化清單的任務。 庫存是項目的集合,因此我們具有以下對象的表示形式:
public class Item {private String ID;private String name;private int quantity;private BigDecimal unitPrice;//getters & setters }期望可以選擇并操作列表中的項目也很有意義。 因此,根據到目前為止的知識和假設,我們可以繼續執行視圖模型。
public class InventoryVM {ListModelList<Item> inventory;Item selectedItem;public ListModelList<Item> getInventory(){inventory = new ListModelList<Item>(InventoryDAO.getInventory());return inventory;}public Item getSelectedItem() {return selectedItem;}public void setSelectedItem(Item selectedItem) {this.selectedItem = selectedItem;}}在這里,我們為View-Model實現提供了一個典型的POJO,以及帶有其getter和setter的數據。
查看實施,“采取行動”
現在,假設我們后來了解到View的要求只是一個簡單的表格顯示:
實現上述UI的可能標記是:
<window title='Inventory' border='normal' apply='org.zkoss.bind.BindComposer' viewModel='@id('vm') @init('lab.zkoss.mvvm.ctrl.InventoryVM')' ><listbox model='@load(vm.inventory)' width='600px' ><auxhead><auxheader label='Inventory Summary' colspan='5' align='center'/> </auxhead><listhead><listheader width='15%' label='Item ID' sort='auto(ID)'/><listheader width='20%' label='Name' sort='auto(name)'/><listheader width='20%' label='Quantity' sort='auto(quantity)'/><listheader width='20%' label='Unit Price' sort='auto(unitPrice)'/><listheader width='25%' label='Net Value'/></listhead><template name='model' var='item'><listitem><listcell><label value='@load(item.ID)'/></listcell><listcell><label value='@load(item.name)'/></listcell><listcell><label value='@load(item.quantity)'/></listcell><listcell><label value='@load(item.unitPrice)'/></listcell><listcell><label value='@load(item.unitPrice * item.quantity)'/></listcell></listitem> </template></listbox> </window>讓我們在這里詳細說明一下標記。
- 在第1行,我們將默認的BindComposer應用于Window組件,該組件使Window的所有子組件均受BindComposer的影響。
- 在下一行,我們指示BindComposer實例化哪個View-Model類,并為View-Model實例提供ID,以便我們對其進行引用。
- 由于我們正在將數據集合加載到列表框,因此在第3行,我們將View-Model實例的屬性“庫存”(即Item對象的集合)分配給列表框的屬性“模型”。
- 然后,在第12行,我們在模板組件上使用該模型。 模板根據收到的模型迭代其封閉的組件。 在這種情況下,我們有5個列表項,它們在列表框中組成一行。
- 在每個Listcell中,我們加載每個對象的屬性并將其顯示在Labels中。
通過ZK的綁定系統,我們能夠訪問View-Model實例中的數據,并使用批注將其加載到View中。
查看實施,“采取兩個”
假設在以后的開發中,我們同意當前的表格顯示在我們的演示文稿中占用了太多空間,并且現在要求我們僅在組合框中選擇該項目時才顯示該項目的詳細信息,如下所示:
盡管表示和行為(僅在用戶選擇時才顯示詳細信息)與我們以前的實現有所不同,但是View-Model類不需要大量修改。 由于僅當在組合框中選中某個項目的細節時才會顯示它的細節,所以很明顯,我們需要處理'onSelect'事件,讓我們添加一個新方法doSelect :
public class InventoryVM {ListModelList<Item> inventory;Item selectedItem;@NotifyChange('selectedItem')@Commandpublic void doSelect(){ }//getters & setters}在我們的例子中,用@Command注釋的方法使其有資格通過其名稱從我們的標記中調用:
<combobox onSelect='@command('doSelect')' >注釋@NotifyChange('selectedItem')允許用戶在組合框中選擇新項目時自動更新selectedItem屬性。 出于我們的目的,方法doSelect不需要其他實現。 完成這些更改后,我們現在可以看到經過稍微修改的View-Model如何與我們的新標記一起工作:
<window title='Inventory' border='normal' apply='org.zkoss.bind.BindComposer' viewModel='@id('vm') @init('lab.zkoss.mvvm.ctrl.InventoryVM')' width='600px'>...<combobox model='@load(vm.inventory)' selectedItem='@bind(vm.selectedItem)' onSelect='@command('doSelect')' ><template name='model' var='item'><comboitem label='@load(item.ID)'/></template><comboitem label='Test'/></combobox><listbox visible='@load(not empty vm.selectedItem)' width='240px'><listhead><listheader ></listheader><listheader ></listheader></listhead><listitem><listcell><label value='Item Name: ' /></listcell><listcell><label value='@load(vm.selectedItem.name)' /></listcell></listitem><listitem><listcell><label value='Unit Price: ' /></listcell><listcell><label value='@load(vm.selectedItem.unitPrice)' /></listcell></listitem><listitem><listcell><label value='Units in Stock: ' /></listcell><listcell><label value='@load(vm.selectedItem.quantity)' /></listcell></listitem><listitem><listcell><label value='Net Value: ' /></listcell><listcell><label value='@load(vm.selectedItem.unitPrice * vm.selectedItem.quantity)' /></listcell></listitem></listbox>... </window>- 在第4行,我們將數據收集清單加載到Combobox的model屬性,以便它可以使用在第7行聲明的Template組件迭代顯示數據模型中每個Item對象的ID。
- 在第5行,selectedItem屬性指向該Item對象列表上最近選擇的Item。
- 在第6行,我們已將onSelect事件映射到View-Model的doSelect方法
- 在第12行,僅當View-Model中的selectedItem屬性不為空時,才使包含項明細的列表框可見(在組合框中選擇一個項之前,selectedItem將保持為空)。
- 然后加載selectedItem的屬性以填充列表框。
概括
在MVVM模式下,我們的View-Model類將其數據和方法公開給活頁夾; 沒有參考任何特定的View組件。 View實現通過綁定器訪問數據或調用事件處理程序。
在本文中,我們僅介紹ZK的MVVM機制的基本原理。 活頁夾顯然不僅限于從視圖模型中加載數據。 除了將數據從View保存到ViewModel之外,我們還可以混合使用View to View-Model通信來注入數據轉換器和驗證器。 MVVM模式也可以與MVC模型結合使用。 也就是說,如果我們愿意的話,我們也可以通過MVC Selector機制連接組件并監聽觸發事件。
我們稍后將深入探討其中一些主題。
參考:我們的JCG合作伙伴 Lance Lu在Tech Dojo博客上對ZK 6中的MVVM進行了初步了解 。
翻譯自: https://www.javacodegeeks.com/2012/06/first-look-at-mvvm-in-zk-6.html
總結
以上是生活随笔為你收集整理的ZK 6中的MVVM初探的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 比较OpenDDR和WURFL
- 下一篇: gt赛车6电脑板(GT赛车PC)