目前尚不清楚您在独立性这里需要什么。你是在寻找与你的数据模型有关的分离,还是你只想为每个渲染单元使用不同的事件侦听器?
关于事件监听器,将听众附加到任何你喜欢的事情上是非常容易的。在ZK中,HTMLBasedComponent是通用根组件之一,支持onClick
,onDoubleClick
,onRightClick
等。
由于这些ZK组件是动态创建的,因此您不能使用@Listen
批注wire event listeners。问题是你没有预先为单元格设置ID。
相反,您需要在渲染时使用programmatically create the 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"/>