2

我在将大型数据集加载到 primefaces 树时遇到问题。

背景

我有一个大数据集,一个大的哈希图列表是具体的。我需要遍历列表的每个元素以在 PostConstruct 方法中构建树,以便显示素面。仅循环遍历列表大约需要 4 分钟。

我是如何处理这个问题的

所以,我想到了在多个线程之间划分循环(是的,这个上下文中的进程是可分割的)以提高性能。我创建线程,其中每个线程循环遍历树的一部分列表构建部分(每个线程每个循环一个树节点)。这使得处理时间缩短到大约一分钟。我想通过在启动时显示树的一部分(如 100 个节点)来进一步增强解决方案,然后让线程完成它们的工作,以保持页面对最终用户的响应。每个线程,在每个循环之后(即在创建树节点之后),都​​应该为 primefaces 触发某种事件(触发方法)以使用新创建的节点更新树。这就是我需要帮助的地方。

问题

我找不到以编程方式告诉 primefaces 更新树的方法。我了解到 RequestContext 用于此目的,但问题是从另一个线程调用它时它会失败。所以我想知道你是否有更好的方法来解决这个问题,或者告诉我我错过了什么。

简单的演示代码

xhtml 文件看起来像这样

<h:form id="form">
    <h3 style="margin-top:0">Client</h3>
         <p:tree value="#{treeBasicView.root}" var="node" id="clientTree">
                <p:treeNode>
                    <h:outputText value="#{node}" />
                </p:treeNode>
            </p:tree>

</h:form>

托管 Bean 看起来像这样

@ManagedBean(name = "treeBasicView")
@ViewScoped
public class BasicView implements Serializable {

    private static TreeNode root;

    @PostConstruct
    public void init() {
        root = new DefaultTreeNode("Root", null);
        TreeNode node0 = new DefaultTreeNode("Node 0", root);
        TreeNode node1 = new DefaultTreeNode("Node 1", root);

        TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);
        TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);

        TreeNode node10 = new DefaultTreeNode("Node 1.0", node1);

        node1.getChildren().add(new DefaultTreeNode("Node 1.1"));
        node00.getChildren().add(new DefaultTreeNode("Node 0.0.0"));
        node00.getChildren().add(new DefaultTreeNode("Node 0.0.1"));
        node01.getChildren().add(new DefaultTreeNode("Node 0.1.0"));
        node10.getChildren().add(new DefaultTreeNode("Node 1.0.0"));
        root.getChildren().add(new DefaultTreeNode("Node 2"));

        BackgroundThread t1 = new BackgroundThread();
        t1.index = 5;
        t1.view = this;
        t1.setName("BGT 1");
        BackgroundThread t2 = new BackgroundThread();
        t2.index = 15;
        t2.view = this;
        t2.setName("BGT 2");
        t1.start();
        t2.start();
    }

    public TreeNode getRoot() {
        return root;
    }

    public synchronized void updateTree(TreeNode node) {
        root.getChildren().add(node);
    }
}

后台线程如下所示:

public class BackgroundThread extends Thread {

    public int index;
    public BasicView view;

    @Override
    public void run() {
        int end = index + 10;
        while (index < end) {
            System.out.println(getName() + ": Node BG " + index);
            view.updateTree(new DefaultTreeNode("Node BG: " + index));
            index += 1;
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                Logger.getLogger(BackgroundThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

这在向树中添加新项目方面确实有效。但是我不能调用任何东西来以编程方式更新primefaces中的树。我的意思是,对象根(托管 bean 中的 TreeNode 类型)得到更新,但这并没有反映在 xhtml 页面中。

眼镜

我正在使用 JSF 2.2 和 primefaces 5.3。

4

0 回答 0