目前尚不清楚您在这里的独立性方面究竟需要什么。您是在寻找数据模型方面的分离,还是只想为每个渲染的单元格设置不同的事件侦听器?
关于事件侦听器,很容易将侦听器附加到您想要的任何东西上。在 ZK 中,HTMLBasedComponent是常见的根组件之一,并且支持onClick
、onDoubleClick
、onRightClick
等。
由于这些 ZK 组件是动态创建的,因此您无法将事件侦听器与@Listen
注释连接。问题是您事先没有单元格的 id。
相反,您需要在渲染时以编程方式创建。EventListener
// in your RowRenderer
public void render(Row row, Data data, int index) {
Label column1 = new Label(data.getOne());
Label column2 = new Label(data.getTwo());
column1.setParent(row);
column2.setParent(row);
column1.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
public void onEvent(Event event) {
// handle event
}
});
column2.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
public void onEvent(Event event) {
// handle event
}
});
}
请注意,正如此处实现的那样,您EventListener
为每个渲染的单元格创建一个新的。这不是很有效,所以如果你可以让你的EventListener
无状态并将必要的数据附加到它Label
本身,你可以节省大量的计算。
关于代码分离,如果您的数据模型是面向列的而不是按行的,那么您将找不到适合这种情况的标准 ZK 组件。也就是说,组件喜欢Grid
和Listbox
被渲染为从顶部开始的行使用RowRenderers
等。如果这是您的问题,您将需要推出自己的组件。这比听起来容易得多。
public class ColumnGrid extends Hlayout {
private ColumnListModel model;
private ColumnRenderer<? extends Component> renderer;
public void setModel(ColumnListModel model) {
this.model = model;
}
public void setRenderer(ColumnRenderer renderer) {
this.renderer = renderer;
}
public void onCreate() {
for (int i=0; i<model.size(); i++) {
Column col = new Column();
appendChild(col);
renderer.render(col, model.getElementAt(i), i);
}
}
}
public class Column extends Vlayout {}
public interface ColumnRenderer<T extends Component> {
render(Column column, T data, int index);
}
它只是一个骨架,但你明白了。
然后,您甚至可以在zul
文件中使用它:
<?component name="colGrid" class="com.sean.is.cool.ColumnGrid" ?>
<colGrid model="myModel" renderer="myColRenderer"/>