wicket ExportToolbar未在表更新

时间:2017-03-04 23:38:09

标签: wicket

在更新表格内容时,我在更新ExportToolbar时遇到了一些问题。我第一次单击CSV导出链接它工作正常,但如果表更新,我再次单击CSV链接,我得到相同的前一个表内容的导出。我将尝试显示设置以及数据如何变化。我希望有人之前已经看过这种行为并且可以把我指向正确的地方。我已经使用了wicket 9年了,从来没有像我一样陷入困境。提前感谢您的帮助。

Wicket版本7.7.0,oops no 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);
}

所以表格正在更新,我的提供商有一个像冠军一样工作的更新方法,但我似乎无法弄清楚为什么导出工具栏在第一次导出后没有更新,而我&#39 ; m担心属性模型也不会更新文件名。这很奇怪,并且似乎没有遵循通常的wicket模型更新行为。

有人出口工具栏有这样的问题,或者我做错了什么,或者没有做正确的事情?谢谢你的帮助。

(编辑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数据不被缓存?

1 个答案:

答案 0 :(得分:1)

得到了答案,还有一些比赛。诀窍是覆盖创建导出链接并使ResourceStreamResource然后在其上设置缓存超时。 Wicket有时会伤害......

        exportToolbar = new ExportToolbar(mainTable, new PropertyModel<String>(this,"mainTableExportFileName"), new AbstractReadOnlyModel<String>() {
        @Override
        public String getObject() { return getMainTableExportFileName(); } 
    }) {
        @Override
        protected Component createExportLink(String componentId, final IDataExporter dataExporter ) {
            ResourceStreamResource resource = new ResourceStreamResource() {
                @Override
                protected IResourceStream getResourceStream() {
                    return new DataExportResourceStreamWriter(dataExporter, getTable());
                }
            };
            resource.setFileName(getFileNameModel().getObject() + "." + dataExporter.getFileNameExtension());
            resource.setCacheDuration(Duration.ONE_SECOND);
            return new ResourceLink<Void>(componentId, resource).setBody(dataExporter.getDataFormatNameModel());
        }
    };