【发布时间】:2017-07-24 23:12:03
【问题描述】:
更新表格内容时,我在更新 ExportToolbar 时遇到了一些问题。我第一次单击 CSV 导出链接时它工作正常,但是如果表已更新并再次单击 CSV 链接,我会导出相同的先前表内容。我将尝试展示设置,以及数据如何变化。我希望有人以前见过这种行为,并能指出我正确的地方。我已经使用 wicket 9 年了,从来没有像现在这样陷入困境。提前感谢您的帮助。
Wicket 版本 7.7.0,哎呀,没有 7.4.0(编辑 1),抱歉
这里是表的定义:
//main report table init:
List<ReportRow> records = db.getVisitCountsByGrouping( getSelectedMonth());
mainProvider = new SearchProvider<>( records, "id" );
mainProvider.setSummationRow(sumRow);
this.mainColumns = new ArrayList<>();
//...columns added....
mainTable = new DefaultDataTable<ReportRow,String>("mainTable", mainColumns, mainProvider, 25);
mainTable.setOutputMarkupId(true);
rft = new ReportFooterToolbar(mainTable, sumRow, this);
rft.setOutputMarkupId(true);
mainTable.addBottomToolbar(rft);
exportToolbar = new ExportToolbar(mainTable, new PropertyModel<String>(this,"mainTableExportFileName"));
exportToolbar.addDataExporter(new CSVDataExporter());
mainTable.addBottomToolbar(exportToolbar);
add(mainTable);
这里是更新的 Ajax 调用者:
Form form = new Form("form");
ArrayList<String> months = new ArrayList<>();
months.add("January");
months.add("February");
months.add("March");
months.add("April");
months.add("May");
months.add("June");
months.add("July");
months.add("August");
months.add("September");
months.add("October");
months.add("November");
months.add("December");
DropDownChoice<String> selectMonth = new DropDownChoice<String>("selectMonth", new PropertyModel<String>(this, "selectedMonth"), months);
selectMonth.add(new AjaxFormComponentUpdatingBehavior("change") {
@Override
protected void onUpdate(AjaxRequestTarget target) {
updateMainTable(target);
}
});
form.add(selectMonth);
add(form);
方法updateMainTable(target):
public void updateMainTable( AjaxRequestTarget target ) {
List<ReportRow> records = db.getVisitCountsByGrouping( getSelectedMonth());
mainProvider.update(records);
target.add(rft);
target.add(mainTable);
}
所以表格更新得很好,我的提供者有一个更新方法,就像一个冠军,但我似乎无法弄清楚为什么在第一次导出后导出工具栏没有更新,我担心属性模型也没有更新文件名。这很奇怪,似乎没有遵循通常的检票口模型更新行为。
有没有人在导出工具栏上遇到过这样的问题,或者我做错了什么,或者没有正确做某事?感谢您的帮助。
(编辑 1):还添加了搜索提供程序的来源:
public class SearchProvider<T> extends SortableDataProvider {
private List<T> list = null;
private ReportRow sumRow = null;
@SuppressWarnings("unchecked")
public SearchProvider( List<T> listOfStuffs, String sortColumn ) {
this(listOfStuffs, sortColumn, true);
}
@SuppressWarnings("unchecked")
public SearchProvider( List<T> listOfStuffs, String sortColumn, boolean ascendingFlag ) {
if( listOfStuffs == null )
listOfStuffs = new ArrayList<>();
this.list = listOfStuffs;
setSort(sortColumn, (ascendingFlag?SortOrder.ASCENDING:SortOrder.DESCENDING) );
}
public void update( List<T> listOfStuffs ) {
if( listOfStuffs == null )
listOfStuffs = new ArrayList<>();
this.list = listOfStuffs;
if( sumRow != null ) {
//update sums
sumRow.resetSums();
for( T t : list ){
sumRow.add((ReportRow)t);
}
}
}
private SortableDataProviderComparator comparator = new SortableDataProviderComparator();
public void setSummationRow(ReportRow sumRow) {
this.sumRow = sumRow;
sumRow.resetSums();
for( T t : this.list ){
sumRow.add((ReportRow)t);
}
}
class SortableDataProviderComparator implements Comparator<T>, Serializable {
@SuppressWarnings("unchecked")
public int compare( final T b1, final T b2 ) {
PropertyModel<Comparable> c1 = new PropertyModel<Comparable>(b1, getSort().getProperty().toString());
PropertyModel<Comparable> c2 = new PropertyModel<Comparable>(b2, getSort().getProperty().toString());
if( c1.getObject() == null && c2.getObject() == null ) return 0;
if( c1.getObject() == null ) return 1;
if( c2.getObject() == null ) return -1;
int result = c1.getObject().compareTo( c2.getObject() );
if( !getSort().isAscending() ) result *= -1;
return result;
}
}
public Iterator<T> iterator( final long first, final long count ) {
Collections.sort( this.list, comparator );
return this.list.subList( (int)first, (int)(first+count) ).iterator();
}
public IModel<T> model( final Object o ) {
return new AbstractReadOnlyModel<T>() {
@Override
@SuppressWarnings("unchecked")
public T getObject() { return (T) o; }
};
}
public long size() { return list.size(); }
}
(编辑 2)另一个更新:我在 ExportToolbar.onConfigure() 方法中添加了一些日志记录,以确保我的提供程序正常工作并且一切正常,问题可能出在 CSVDataExporter 本身吗?
这是我的调试日志和输出:
exportToolbar = new ExportToolbar(mainTable, new PropertyModel<String>(this,"mainTableExportFileName")) {
@Override
protected void onConfigure() {
super.onConfigure();
//setFileNameModel( new Model<String>( getMainTableExportFileName() ));
if( getFileNameModel() != null )
logger.debug("ExportToolbar file name model: "+ getFileNameModel().toString() +" file name: "+ getFileNameModel().getObject() );
Iterator it = getTable().getDataProvider().iterator(0, getTable().getDataProvider().size());
while( it.hasNext() ) {
ReportRow r = (ReportRow) it.next();
logger.debug("ExportToolbar data: "+ r.getCategory() +" "+ r.get1() +" "+ r.get2() + " "+ r.get3() );
}
}
};
日志文件:
2017-03-06 12:28:52 DEBUG ReportPanel:244 - ExportToolbar file name model: Model:classname=[org.apache.wicket.model.PropertyModel]:nestedModel=[[ReportPanel [Component id = panel]]]:expression=[mainTableExportFileName] file name: 2017-January-AllVisits-ByReason
2017-03-06 12:28:52 DEBUG ReportPanel:249 - ExportToolbar data: add/drop 0 38 63
2017-03-06 12:28:52 DEBUG ReportPanel:249 - ExportToolbar data: withdraw 0 0 0
2017-03-06 12:28:52 DEBUG ReportPanel:249 - ExportToolbar data: audit 0 0 3
2017-03-06 12:28:52 DEBUG ReportPanel:249 - ExportToolbar data: advising 0 27 35
2017-03-06 12:28:52 DEBUG ReportPanel:249 - ExportToolbar data: prospective 0 2 0
2017-03-06 12:28:52 DEBUG ReportPanel:249 - ExportToolbar data: other 0 19 38
2017-03-06 12:29:26 DEBUG ReportPanel:244 - ExportToolbar file name model: Model:classname=[org.apache.wicket.model.PropertyModel]:nestedModel=[[ReportPanel [Component id = panel]]]:expression=[mainTableExportFileName] file name: 2017-February-AllVisits-ByReason
2017-03-06 12:29:26 DEBUG ReportPanel:249 - ExportToolbar data: add/drop 3 5 1
2017-03-06 12:29:26 DEBUG ReportPanel:249 - ExportToolbar data: withdraw 0 1 0
2017-03-06 12:29:26 DEBUG ReportPanel:249 - ExportToolbar data: audit 0 3 4
2017-03-06 12:29:26 DEBUG ReportPanel:249 - ExportToolbar data: advising 8 6 6
2017-03-06 12:29:26 DEBUG ReportPanel:249 - ExportToolbar data: prospective 3 1 2
2017-03-06 12:29:26 DEBUG ReportPanel:249 - ExportToolbar data: other 8 8 7
(编辑 3)我能够正确更新文件名属性模型并始终使表导出链接正常工作,但我仍然遇到问题,但我能够通过创建此导出链接来保持一致表再次更新和 addOrReplace(mainTable) 而不是更新它。这就是我能够让 createExportLink() 方法再次运行的方式,否则它只会在创建 ExportToolbar 时发生,并且再也不会发生。所以现在,假设 ExportToolbar 看起来像这样:
exportToolbar = new ExportToolbar(mainTable, new PropertyModel<String>(this,"mainTableExportFileName") ) {
@Override
protected Component createExportLink(String componentId, final IDataExporter dataExporter ) {
logger.debug("createExportLink: "+ componentId +" exporter: "+ dataExporter.toString());
Component component = super.createExportLink(componentId, dataExporter);
return component;
}
};
exportToolbar.addDataExporter(new CSVDataExporter() );
现在的诀窍似乎是,如果我在浏览器中删除历史记录并单击链接,一切都会正常工作,但否则动态更改表格并选择链接会为我提供上次单击链接时的数据。所以看起来链接被缓存了。我正在渗透组件创建,如何更改组件以确保不缓存 csv 数据?
【问题讨论】:
-
我认为该错误必须在 SearchProvider 类中。 CSVDataExporter 在其
#exportData()方法中使用dataProvider。你确定你使用 7.7.0 吗?它尚未发布。 -
您能否发布您的 SearchProvider 类源代码(主要是方法 iterator() 和 update(records)。您似乎在某处有错误。文件名可能不会更新,因为我看不到在哪里你更新它。你使用一个属性模型,所以我希望你的页面上有一个属性
mainTableExportFileName。我进一步期望,你在你的updateMainTable方法中改变它,但你没有。 -
不知道为什么我输入了 7.7.0,我使用的是 7.4.0,我应该压缩搜索提供程序以提高可读性。感谢您的耐心等待。
标签: wicket