-
FEATURED COMPONENTS
First time here? Check out the FAQ!
I see many examples with List<String> xxx
object is used in Zul code.
<Combobox model='xxx' />
I checked Combobox.java and see setModel signature as follows:
public void setModel(ListModel<?> model) {
I am not very clear how List<String>
converts to ListModel when the model is set to Combobox object. I believe some behind-the-scene operations converts List<Sometype>
object to ListModel<Sometype>
. Can you explain how it works?
See if this zk-combobox-with-item-rendered will help to understand it.
This seems to explain why List<string> works good for model.
http://books.zkoss.org/wiki/ZK_Developer's_Reference/MVC/View/Renderer/Combobox_Renderer (Combobox Renderer)
When a combobox is assigned with a model, a default renderer is assigned too. The default renderer will assume that the combobox displays the data as a string. If you want to display more sophisticated information or retrieve a particular field of the data, you have to implement ComboitemRenderer to handle the rendering.
I was a little bit confused about the question. Now, I realize that this is binding/annotation question.
From ZK http://www.zkoss.org/zkdemo/combobox/simple_combobox (Example)
ViewModel is as follows:
public class ShirtViewModel {
public List<String> getColors() {
return ShirtData.getColors();
}
ZUL code
<combobox id="cmbColor" width="150px"
model="@load(vm.colors)" selectedItem="@bind(vm.shirtColor)">
<template name="model">
<comboitem label="@load(each)"
image="@load(vm.getIconImage(each))" />
</template>
</combobox>
I believe the zul code, @load(vm.colors)
whose colors from List<String> getColors()
, manages convert List<String>
to ListModel<String>
. I think Binder kicks in to call some methods to convert them. Anyone knows what part of code does the job?
Annotation Attributes - CONVERTER
http://books.zkoss.org/wiki/ZK_Component_Reference/Annotation/Data_Binding (Data Binding)
It looks ComboboxModelConverter does its job. Method super.coerceToUi() does its job to convert List to ListModel.
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object coerceToUi(Object val, C comp, BindContext ctx) {
if (val == null) {
val = new ArrayList();
}
ListModel model = null;
if (val instanceof ListModel) {
BindELContext.addModel(comp, val); //ZK-758. @see AbstractRenderer#addItemReference
return val;
} else if (val instanceof Set) {
model = new ListModelSet((Set)val, false);//ZK-1528, doesn't use live
} else if (val instanceof List) {
//ZK-1528, doesn't use live,
//user should use ListModel if he want to dynamically change inside element.
model = new ListModelList((List)val, false);
} else if (val instanceof Map) {
model = new ListModelMap((Map)val, false);//ZK-1528, doesn't use live
} else if (val instanceof Object[]) {
model = new ListModelArray((Object[]) val, false);//ZK-1528, doesn't use live
} else if ((val instanceof Class) && Enum.class.isAssignableFrom((Class)val)) {
model = new ListModelArray((Object[]) ((Class)val).getEnumConstants(), false);//ZK-1528, doesn't use live
} else if (val instanceof GroupsModel) { //feature#2866506: Data Binding shall support GroupsModel with Listbox/Grid
model = GroupsListModel.toListModel((GroupsModel) val);
} else {
throw new UiException("Expects java.util.Set, java.util.List, java.util.Map, Object[], Enum Class, GroupsModel, or ListModel only. "+val.getClass());
}
// final Container container = new Container(model);
final ListModel compModel = getComponentModel(comp);
if(compModel instanceof Selectable){
Selectable selectable = ((Selectable)compModel);
((Selectable) model).setMultiple(selectable.isMultiple());
//Should we check the contains? it has O(m) issue and O(mn) in array case
//if not, there is a issue if the new data doesn't contains the selected obj
// for(Object selected:container.contains(selectable.getSelection())){
// ((Selectable) model).addToSelection(selected);
// }
//no need to check contains, user should remove the selection if it is not in current list anymore
//that could be done by binding to selectedItem or selectedItems
for(Object selected:selectable.getSelection()){
((Selectable) model).addToSelection(selected);
}
}
model = handleWrappedModel(ctx,comp,model);
BindELContext.addModel(comp, model); //ZK-758. @see AbstractRenderer#addItemReference
return model;
}
Asked: 2013-08-13 18:44:44 +0800
Seen: 41 times
Last updated: Aug 14 '13