2012-12-11 55 views
0

我將要使用的數據在列表框中的Java類綁定,而不是純Java在ZK列表框綁定與itemRenderer的

@bind

隨着每的ListCell。 我試着用這個例子

我ZUL文件...

<zk> 
    <window border="normal" title="hello" apply="org.zkoss.bind.BindComposer" 
     viewModel="@id('vm') @init('com.test.binding.TestRenderer')" > 
    <button label="ClickMe" id="retrieve" 
         onClick="@command('onOK')"> 
        </button> 
    <div height="800px"> 
     <listbox model="@load(vm.model)" itemRenderer="@load(vm.itemRenderer)" vflex="true" multiple="true"/> 
    </div> 
    </window> 
</zk> 

我的Java類或視圖控制器.....

package com.test.binding; 

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.List; 

import org.zkoss.bind.annotation.AfterCompose; 
import org.zkoss.bind.annotation.Command; 
import org.zkoss.bind.annotation.ContextParam; 
import org.zkoss.bind.annotation.ContextType; 
import org.zkoss.zk.ui.Component; 
import org.zkoss.zkplus.databind.AnnotateDataBinder; 
import org.zkoss.zkplus.databind.Binding; 
import org.zkoss.zkplus.databind.BindingListModelList; 
import org.zkoss.zul.ListModel; 
import org.zkoss.zul.ListModelList; 
import org.zkoss.zul.Listcell; 
import org.zkoss.zul.Listitem; 
import org.zkoss.zul.ListitemRenderer; 
import org.zkoss.zul.Textbox; 


public class TestRenderer { 

    ListModelList model = new ListModelList(); 
    private AnnotateDataBinder binder; 

    @AfterCompose 
    public void afterCompose(@ContextParam(ContextType.VIEW) Component view) { 
     binder = new AnnotateDataBinder(view); 
    List persons = new ArrayList();  
    model.add(new Person("David", "Coverdale")); 
    model.add(new Person("Doug", "Aldrich")); 
    model.add(new Person("Reb", "Beach")); 
    model.add(new Person("Michael", "Devin")); 
    model.add(new Person("Brian", "Tichy")); 


     binder.loadAll(); 


    } 

    public void setModel(ListModelList model) { 
     this.model = model; 
    } 

    public ListModel getModel() { 

     return model; 
    } 

    // method for ZK 6 
    public ListitemRenderer getItemRenderer() { 
     ListitemRenderer _rowRenderer = null; 
     if (_rowRenderer == null) { 

      _rowRenderer = new ListitemRenderer() { 
       public void render(final Listitem item, Object object, 
         int index) throws Exception { 
        final Person dataBean = (Person) object; 

        binder.bindBean(item.getId() , dataBean); 

        Listcell cell = new Listcell(); 
        Textbox name = new Textbox(); 
        name.setValue(dataBean.getFirstName()); 
        System.out.println(item.getId()+ "------------------>"+item.getId() + ".name"); 
        //binder.addBinding(name, "value", item.getId()+i + ".name", null, null, "both", null, null, null, null); 
        //binder.addBinding(name, "value",item.getId() + ".name", new String[] {}, "none", "both", null); 
        cell.appendChild(name); 
        //cell.addAnnotation(cell, "bind", null); 
        cell.setParent(item); 

       } 
      }; 
      binder.saveAll(); 
      binder.loadAll(); 
     } 
     return _rowRenderer; 
    } 
    @Command 
    public void onOK() { 
     binder.saveAll(); //load Inputfields from Form, Constraints will be performed 

     binder.loadAll(); 
     Collection<Binding> test = binder.getAllBindings(); 
     System.out.println(model); 
     } 
    public class Person { 
     private String firstName; 
     private String lastName; 

     public Person(String fn, String ln) { 
      setFirstName(fn); 
      setLastName(ln); 
     } 

     public String getFirstName() { 
      return firstName; 
     } 
     public void setFirstName(String fn) { 
      firstName = fn; 
     } 

     public String getLastName() { 
      return lastName; 
     } 
     public void setLastName(String ln) { 
      lastName = ln; 
     } 

    } 

    @Command 
    public void clickMe(){ 
     BindingListModelList blml = (BindingListModelList) getModel(); 

     for (Object object : blml) { 
      System.out.println(Integer.parseInt((String) object)); 
     } 
    } 
} 

任何一個可以給我演示示例如何綁定應與

getItemRendered()

列表框

感謝

回答

0

在我看來,在MVVM中使用ListitemRenderer並不是那麼糟糕,有時它可能是zul頁面和ViewModel之間的'橋樑',它可以被看作是組件的一部分(因爲一旦你分配了一個模型,listbox將會如果不指定模板或自定義渲染器,請使用默認渲染器渲染項目)(請參閱List Model)。如果沒有什麼不好,只分配默認渲染器的模型和渲染項目,那麼沒有什麼不好的方法來分配模型和自定義渲染器來渲染項目。

讓我們先定義好'好': - zul文件不需要知道ViewModel是如何工作的,只需要詢問數據和觸發命令即可。 - ViewModel不需要知道zul頁面中的任何內容,只需提供數據並處理一些預定義的事件即可。

現在正在考慮類似的官方文件中描述的一個簡單的場景: Performing Actions on Events

看到這一行

onClick="@command('deleteOrder', cartItem=cartItem)" 

這行

public void deleteOrder(@BindingParam("cartItem") CartItem cartItem) 

在這種情況下, zul頁面需要知道在事件觸發時將param引入deleteOrder命令,甚至必須知道參數應該分配給在ViewModel中名爲cartItem的變量。另一方面,ViewModel需要檢索從zul頁面傳遞的參數。

這顯然不是'好'的情況。

用的ListItemRenderer,讓我們說ShoppingcartOrderlistItemRenderer,我們可以簡單地與所需的數據事件發佈到列表框(例如,onDeleteOrder),然後使它成爲

<listbox onDeleteOrder="@command('deleteOrder')" ... 

public void deleteOrder(@ContextParam(ContextType.TRIGGER_EVENT) DeleteOrderEvent event) { 
    getShoppingCart().remove(event.getProductId()); 
} 

依靠在一個事件中,而不是依賴於在zul頁面中定義的參數,我認爲這更強大。最後,還不得不說,只是個人意見。

+0

嗨Benbai,我有限制使用itemrendered()由於重新排序和排序 –

+0

另一方面,我不要以爲這是一種好的方式,如果MVVM有一些機制來做類似的工作會更好。 – benbai123

+0

但是,如果您正在使用重新排序並將該訂單保存到數據庫中,則很難純粹在zul中使用listbox,因爲您已經修復了zul中的listcell,並且它不會滿足要求。您可以提供一些使用getitemrendered進行數據綁定的示例將非常有幫助 –

3

您正在嘗試混合不同的範式。你想要使用數據綁定,特別是MVVM樣式,但也要在過程中引入自定義渲染器。即使這有效,我認爲這是一個非常糟糕的做法。無論是純粹的MVVM數據綁定,您將視圖從模型中分離出來,只需在視圖中定義綁定,或者使用純MVC並使用您自己的渲染器無論如何都可以呈現模型數據。

數據綁定的要點是讓綁定器負責基於數據綁定註釋來渲染/更新組件狀態。

專門談論你的示例代碼在這裏使用的是org.zkoss.bind.BindComposer,它會自動初始化粘合劑實例之後,你也是明確實例在@AfterCompose單獨AnnotateDataBinder所以會有這兩個之間的衝突。

我的建議是由introdcing在你看來<template>純MVVM綁定去,讓MVVM粘結劑使用@Bind@Load註釋呈現此模板或用爲本「MVVM in Java」文章

中描述的純Java風格MVVM綁定走
+0

謝謝,但我不能使用@bind因爲在我的名單我使用Soring和reorde因此我無法修復ZUl FIle中的單元格。任何其他建議 –

+0

您能否告訴列表框重新使用將使用MVVM –