瓦丁树。懒加载

时间:2012-03-19 15:37:51

标签: tree lazy-loading vaadin

我正在尝试在节点Expand Events上实现延迟加载元素。 这有一个问题。 因此,在展开事件中,我使用

为展开的节点创建新项目
HierarchicalContainer.addItem() 

但是这个方法调用

containerItemSetChange()

AbstractSelect类的方法。有

itemIdMapper.removeAll()

被调用。因此清理地图并且所有树项都在地图中获得新的ID。当服务器的答案到达客户端时,它不知道这个新的id,因为它具有先前的id(扩展节点),因此不会添加新项目而不会在客户端呈现。

我试过https://vaadin.com/forum/-/message_boards/view_message/131802。但实际上,整个树的数据是从服务器发送到客户端的。我希望只发送特定节点所需的数据。所以没有性能“+”。

任何人都可以帮我解决这个问题吗?提前谢谢。

版本

实际上我还需要改变字段

partialUpdate

为true,因为在第一台服务器将树的所有内容发送到客户端。

2 个答案:

答案 0 :(得分:3)

解释你的问题;大多数人都会认为树在你的对象上使用你的hashcode / equals实现(这就是为什么它们在那里!)进行比较。你创建你的树,做一些其他的东西,包括修改你放在树中的项目,然后尝试使用这些项目作为键修改树。

这是问题所在。

当您调用addItem()时,树基本上会获取项目哈希码的快照。内部使用该哈希码将客户端工件映射到服务器上的对象。对于任何后续removeItem()等调用,它只使用该快照哈希码,而不是像任何其他普通容器一样调用对象的哈希码/等于方法。如果您通过removeItem()进行调试,您会很快看到问题所在。

  • 简单解决方案:一旦将对象放入其中,就不要修改它们 树。但如果你这样做,你需要重建整棵树。
  • 更好的解决方案:创建代理对象(TreeNode或其他内容) 它包含项目但提供了自己的equals / hashcode 方法。
  • 最佳解决方案: Vaadin重做树,使其表现得更好 像一个标准的java容器。目前看来,这个古怪 在方法的javadoc中没有提到行为 将会失败。

希望这有助于某人。

答案 1 :(得分:1)

尽管在Vaadin文档中它表示Tree的延迟加载是not supported,但我设法实现了以下延迟加载 Hierarchical接口。

将所有元素存储在本地结构中非常重要(在HashMap hierarchy的情况下),不要多次读取元素这不起作用。我认为因为Vaadin不使用equals()hashCode()

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.softmodeler.common.CommonPlugin;
import com.softmodeler.model.OutputNode;
import com.softmodeler.service.IViewService;
import com.vaadin.data.Container.Hierarchical;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.BeanItem;

/**
 * @author Flavio Donzé
 * @version 1.0
 */
public class OutputNodeHierachical implements Hierarchical {
    private static final long serialVersionUID = 8289589835030184018L;

    /** the view service */
    private IViewService service = CommonPlugin.getService(IViewService.class);

    /** collection of all root nodes */
    private List<OutputNode> rootNodes = null;
    /** parent=>children mapping */
    private Map<OutputNode, List<OutputNode>> hierarchy = new HashMap<>();

    /**
     * constructor
     *
     * @param rootNodes collection of all root nodes
     */
    public OutputNodeHierachical(List<OutputNode> rootNodes) {
        this.rootNodes = Collections.unmodifiableList(rootNodes);

        addToHierarchy(rootNodes);
    }

    @Override
    public Collection<?> getChildren(Object itemId) {
        try {
            List<OutputNode> children = hierarchy.get(itemId);
            if (children == null) {
                OutputNode node = (OutputNode) itemId;
                children = service.getChildren(node.getNodeId(), false);

                hierarchy.put(node, children);

                // add children to hierarchy, their children will be added on click
                addToHierarchy(children);
            }
            return children;
        } catch (Exception e) {
            VaadinUtil.handleException(e);
        }
        return null;
    }

    /**
     * add each element to the hierarchy without their children hierarchy(child=>null)
     *
     * @param children elements to add
     */
    private void addToHierarchy(List<OutputNode> children) {
        for (OutputNode child : children) {
            hierarchy.put(child, null);
        }
    }

    @Override
    public boolean areChildrenAllowed(Object itemId) {
        return !((OutputNode) itemId).getChilds().isEmpty();
    }

    @Override
    public boolean hasChildren(Object itemId) {
        return !((OutputNode) itemId).getChilds().isEmpty();
    }

    @Override
    public Object getParent(Object itemId) {
        String parentId = ((OutputNode) itemId).getParentId();
        for (OutputNode node : hierarchy.keySet()) {
            if (node.getNodeId().equals(parentId)) {
                return node;
            }
        }
        return null;
    }

    @Override
    public Collection<?> rootItemIds() {
        return rootNodes;
    }

    @Override
    public boolean isRoot(Object itemId) {
        return rootNodes.contains(itemId);
    }

    @Override
    public Item getItem(Object itemId) {
        return new BeanItem<OutputNode>((OutputNode) itemId);
    }

    @Override
    public boolean containsId(Object itemId) {
        return hierarchy.containsKey(itemId);
    }

    @Override
    public Collection<?> getItemIds() {
        return hierarchy.keySet();
    }

    @Override
    public int size() {
        return hierarchy.size();
    }

    @Override
    public boolean setParent(Object itemId, Object newParentId) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Item addItem(Object itemId) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Object addItem() throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean removeItem(Object itemId) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean removeAllItems() throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Class<?> getType(Object propertyId) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Collection<?> getContainerPropertyIds() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Property<?> getContainerProperty(Object itemId, Object propertyId) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean addContainerProperty(Object propertyId, Class<?> type, Object defaultValue) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean removeContainerProperty(Object propertyId) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

}

将容器添加到Tree,如下所示:

OutputNodeHierachical dataSource = new OutputNodeHierachical(rootNodes);

Tree mainTree = new Tree();
mainTree.setSizeFull();
mainTree.setContainerDataSource(dataSource);
mainTree.addItemClickListener(new ItemClickListener() {
    private static final long serialVersionUID = -413371711541672605L;

    @Override
    public void itemClick(ItemClickEvent event) {
        OutputNode node = (OutputNode) event.getItemId();
        openObject(node.getObjectId());
    }
});


我希望这个例子有所帮助,因为我在互联网上找不到真实的例子。