I will want to use Data binding in Java Class rather than
@bind
With each ListCell in Listbox.
I tried with this example
My ZUl File…
<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>
My Java Class or ViewController…..
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));
}
}
}
Can any one give me the Demo Example How Binding should work with
getItemRendered()
In Listbox
Thanks
In my opinion, using ListitemRenderer with MVVM is not so bad, sometimes it can be the ‘bridge’ between zul page and ViewModel, and it can be considered as a part of component (since once you assign a model, listbox will use default renderer to render item if you do not assign a template or a custom renderer) (see List Model). If there is nothing bad that assign only model and render items by default renderer, there is nothing bad assign both model and custom renderer to render items.
Let’s define what the ‘good’ is at first:
— The zul file do not need to know how ViewModel works, just ask for data and trigger command as needed.
— The ViewModel do not need to know anything in zul page, just provide data and process some predefined event.
Now thinking about a simple scenario like the one described in the official document:
Performing Actions on Events
see this line
and this line
In this case, the zul page need to know bring the param to deleteOrder command while event triggered, and even have to know the param should assign the variable named cartItem in ViewModel. On the other hand, the ViewModel need to retrieve the param passed from zul page.
This is obviously not the ‘good’ situation.
With the ListitemRenderer, let’s say ShoppingcartOrderlistItemRenderer, we can simply post an event to Listbox (e.g., onDeleteOrder) with the required data, then make it becomes
and
Rely on an event instead of rely on a param defined in zul page, I think this is more robust.
Finally, still have to say, just personal opinion.