【发布时间】:2016-09-20 12:55:49
【问题描述】:
希望你能帮我解决这个问题,因为这几天一直困扰着我。
我有一个 wicket DataTable 填充 16 列。每行都可以有一些子信息(如果它有一个“+”按钮显示在第一个单元格中)。由于子信息只是一些带有输入日期的常规文本,因此我不想使用真正的 TreeData 对象。我一直在尝试将“+”按钮变成一个 AjaxFallbackButton,它可以工作,但是我的子数据呈现在该行的第一个单元格内,这是非常不切实际的。
我现在正在尝试通过在目标上添加一些 JS 来动态创建新行:
target.prependJavaScript(String.format("var item=document.createElement(\"tr\"); item.id=\"%s\"; $(\"#%s\").after(item);", newChild.getId(), rowId));
这很棒,因为它实际上在我的页面内创建了一个新标签。但是如何在这个新渲染的 HTML 中获取我的新数据呢?我想我的问题是 Wicket 不“知道”新行,如果我将新的 wicket Item(Wicket 中带有新行的容器)添加到 Wicket DataTable 并将 DataTable 的主体添加到目标然后现在呈现我的新行已经完成了。
我的页面标记: [桌子]
我的自定义 DataTable 扩展 Java 代码(扩展以确保添加了所有 outputMarkUp): @覆盖 受保护的无效 onInitialize() { super.onInitialize(); this.addTopToolbar(new NavigationToolbar(this)); this.addTopToolbar(new HeadersToolbar(this, (ISortableDataProvider)this.getDataProvider())); this.addBottomToolbar(new NoRecordsToolbar(this)); this.setOutputMarkupId(true); }
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(CssReferenceHeaderItem.forReference(WarehouseToolbarCssReference.get()));
}
@Override
protected Item<T> newRowItem(String id, int index, IModel<T> model) {
Item<T> item = super.newRowItem(id, index, model);
this.lastId = Integer.valueOf(id);
item.setMarkupId(this.getId() + item.getId());
return item;
}
第一列使用自定义面板来填充列中的单元格,但经过大量尝试和测试,我实际上最终得到了来自 Wicket 本身的常规节点:
<wicket:panel xmlns:wicket="http://wicket.apache.org">
<a wicket:id="junction"></a>
<span wicket:id="content" class="tree-content">[content]</span>
cellspacing="0" wicket:id="reasonData">[Reason data]</table>-->
</wicket:panel>
最后是创建新行并填充必要数据(它本身就是一个新的 DataTable)并填充 ajax-target 的代码:
public void onClick(AjaxRequestTarget target) {
Integer currentRowIndex = Integer.valueOf(this.findParent(Item.class).findParent(Item.class).getId());
String rowId = this.findParent(Item.class).findParent(Item.class).getMarkupId();
Item<IColumn<OldOrder, String>> newChild = null;
this.dataTable.setVisible(true);
newChild = new Item<>(String.valueOf(this.findParent(DataTable.class).getLastId() + 1), currentRowIndex * -1, null);
newChild.setOutputMarkupId(true);
target.prependJavaScript(String.format("var item=document.createElement(\"tr\"); item.id=\"%s\"; $(\"#%s\").after(item);", newChild.getId(), rowId));
this.populateChildRow(newChild); // This is where the new row gets filled with the new data
Component rows = this.findParent(DataTable.class).getBody().get("rows");
if (rows instanceof WebMarkupContainer) {
((WebMarkupContainer)rows).add(newChild);
}
target.add(this.findParent(DataTable.class).getBody());
}
// This is where the new row gets filled with the new data
private void populateChildRow(Item<IColumn<ParentClass>, String>> item) {
RepeatingView cells = new RepeatingView("cells"){
@Override // Overridden to check if this gets executed... it doesn't
protected void onAfterRender() {
super.onAfterRender();
String stop = "STOP";
}
};
item.add(cells);
Item<?> cellItem = new Item<>("arbitrary", 1, null);
cells.add(cellItem);
cells.setVisible(false);
cells.setOutputMarkupId(true);
cells.add(AttributeAppender.append("colspan", this.findParent(DataTable.class).getColumns().size()));
this.dataTable.setOutputMarkupId(true);
cellItem.add(this.dataTable); // The DataTable with the child data
}
除了我应该清理一些代码之外,永远不会呈现子数据。有人可以解释一下吗?
【问题讨论】: