ZK Framework:如何触发渲染生成的Listbox内Combobox的onSelect事件
ZK Framework动态生成Combobox的onSelect事件不生效解决方案
问题原因
- 动态生成的Combobox未与Controller建立有效事件绑定:你在Controller中通过
onSelect$myCombobox0这类ID匹配的方式绑定事件,但ZK仅自动绑定ZUL中声明或通过@Wire注入的组件,动态创建的组件无法触发这类方法。 - 未关联Combobox与对应
DocumentoVinculado实体:无法在选择事件中定位到需要更新observaciones字段的目标实体。
修改后的代码实现
1. Controller(NewFileComposer)
import org.zkoss.zk.ui.select.SelectEvent; import org.zkoss.zk.ui.select.annotation.Listen; import org.zkoss.zk.ui.select.annotation.Wire; import org.zkoss.zul.Combobox; import org.zkoss.zul.Comboitem; import org.zkoss.zul.Label; import org.zkoss.zul.ListModelList; import org.zkoss.zul.Listbox; import org.zkoss.zul.Listitem; import org.zkoss.zul.Window; import java.util.ArrayList; import java.util.List; public class NewFileComposer extends BaseController { @Wire private Window myWindow; @Wire private Listbox myListbox; @Wire private Label myLabel; // 监听所有ID以myCombobox开头的Combobox的onSelect事件 @Listen("onSelect = combobox[id^='myCombobox']") public void onComboboxSelect(SelectEvent<Comboitem, String> event) { Combobox combobox = (Combobox) event.getTarget(); // 向上遍历组件树找到对应的Listitem Listitem item = (Listitem) combobox.getParent().getParent(); // 获取当前行对应的DocumentoVinculado实体 DocumentoVinculado doc = (DocumentoVinculado) item.getValue(); // 更新实体的observaciones字段 doc.setObservaciones(combobox.getValue()); // 更新Label显示选中内容 myLabel.setValue(String.format("选中选项: %s | 对应GEBI: %s", combobox.getValue(), doc.getNroGEBI())); } public void onCreate$myWindow() { ListModelList<DocumentoVinculado> modelo = new ListModelList<>(crearLista()); myListbox.setModel(modelo); myListbox.setItemRenderer(new NewFileRender()); } private List<DocumentoVinculado> crearLista() { List<DocumentoVinculado> docVinculados = new ArrayList<>(); docVinculados.add(new DocumentoVinculado("123GEBI1", " ")); docVinculados.add(new DocumentoVinculado("123GEBI2", " ")); return docVinculados; } }
2. ListitemRenderer(NewFileRender)
import org.zkoss.zul.Combobox; import org.zkoss.zul.Comboitem; import org.zkoss.zul.Listcell; import org.zkoss.zul.Listitem; import org.zkoss.zul.ListitemRenderer; import java.util.ArrayList; import java.util.List; public class NewFileRender implements ListitemRenderer<DocumentoVinculado> { @Override public void render(Listitem item, DocumentoVinculado docVinculado, int i) throws Exception { Listcell nroGebiCell = new Listcell(docVinculado.getNroGEBI()); nroGebiCell.setParent(item); Listcell opcionesCell = new Listcell(); opcionesCell.appendChild(comboboxObservaciones(i)); item.appendChild(opcionesCell); // 显式将实体绑定到Listitem,确保事件中能获取到 item.setValue(docVinculado); } private Combobox comboboxObservaciones(int i) { Combobox combobox = new Combobox(); List<String> listaDeOpciones = listaDeOpciones(); for(String opcion : listaDeOpciones) { // 使用构造函数直接创建Comboitem更简洁 Comboitem myComboitem = new Comboitem(opcion); myComboitem.setParent(combobox); } combobox.setId("myCombobox" + i); return combobox; } private List<String> listaDeOpciones() { List<String> opciones = new ArrayList<>(); opciones.add(" "); opciones.add("Opcion1"); opciones.add("Opcion2"); return opciones; } }
关键说明
- 使用
@Listen注解统一监听动态组件:通过combobox[id^='myCombobox']匹配所有动态生成的Combobox,无需为每个组件单独编写事件方法。 - 组件树关联实体:利用Listitem的
getValue()方法获取当前行对应的DocumentoVinculado,确保选中值能准确更新到对应实体的observaciones字段。 - 组件注入:添加
@Wire注解确保ZK能正确注入ZUL中声明的组件(如myListbox、myLabel)。
内容的提问来源于stack exchange,提问作者Matias
相关产品推荐
相关产品推荐

