滚动时加载列表视图

时间:2011-04-05 14:23:53

标签: wicket

我在使用ListView显示文档列表的应用程序时遇到问题: 目前的设计如下:

  • 使用nr项= nrOfdocuments / 50创建ListView; ListView被添加到滚动条

  • 对于此ListView的每个项目,创建一个新面板批处理(代表一批文档 - 最多50个文档);

  • 此Batch类创建另一个包含最多50个项目的ListView(每个项目代表一个带有文档详细信息的面板 - 仅在滚动到达时才加载项目)

例如: - 总共1000个文档:将创建20个Batch类型的对象=>将创建20个ListView对象

问题是尝试加载大量文档(> 10000)将以Java内存不足异常结束。 我想改进这个设计,只保留一个批量加载到内存中一次(所以只有最多50个文档)并清除以前创建的所有其他不再使用的ListView对象。 你有什么想法可以帮助我吗?

4 个答案:

答案 0 :(得分:1)

您只能加载3批次:

  • 当前批次之前的一批
  • 当前批次
  • 当前批次之后的批次

当用户向上/向下滚动列表时,您只能加载这三个批次(当用户输入另一个批次时,使用他们输入的批次作为新的当前批次重新加载批次。)

要使滚动条显示就像列表中装满旧批次一样,只需插入带有空文档的虚拟批次,例如

  • Dummy batch 1
  • Dummy batch 2
  • 当前批次之前的一批
  • 当前批次
  • 当前批次之后的批次

唯一的问题是,如果用户在ajax有时间重新加载批次之前快速搜索了列表。这不容易解决,但可以通过让虚拟批次为每个文档条目显示加载消息来向用户传达正在加载数据的信息。

答案 1 :(得分:0)

不确定你要完成什么......

你想用一组新的50个文件替换当前的50个文件吗?或者你想保留旧文件以便滚动...

如果是前者,你的方法似乎不是我想到的第一个......

private class MyPanel extends Panel {
    private ListView lv;

public MyPanel(String id) {
    super(id);
    List list = new ArrayList();
    lv = new ListView("lv", list) {

        @Override
        protected void populateItem(ListItem item) {
            //display the document
        }

    };

    add(lv);

    add(new AjaxButton("next", new Form("form")) {

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
            //retrieve the next Batch
            List newList = new ArrayList();
            lv.setModelObject(newList);
            target.addComponent(MyPanel.this);
        }

    });
}

}

我想起了一些模糊的东西。你可以像以前一样来回滚动。

除此之外,我想到的是DataView而不是ListView,因为它支持开箱即用的分页。

作为最后一个想法,如果你只删除对ListView的引用而不添加它们(或任何周围的容器,因为转发器不能添加到AjaxRequestTargets),这将使gc有机会清理这些对象但是你重新加载时必须处理空引用...

答案 2 :(得分:0)

这不是严格意义上的与wicket相关的答案,更多的是对您的UI进行假设。

您是否考虑过使用master-detail UI模式?

不是一次性保存顶级文档及其子文档,而是在列表中显示顶级节点,并在单独的“详细信息”中仅显示所选顶级节点的子文档'小组。

在wicket中,这是相当简单的,类似onClick事件更新'detail'面板的模型(拉动所选父项的子文档)。

答案 3 :(得分:0)