2012-03-19 97 views
4

我正试图在节点Expand Events上实现延迟加载元素。 这有一个问题。 于是就展开事件,我创建展开的节点的新项目使用Vaadin树。延迟加载

HierarchicalContainer.addItem() 

但这种方法调用AbstractSelect类的

containerItemSetChange() 

方法。有

itemIdMapper.removeAll() 

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

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

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

其实我也需要

partialUpdate 

改变字段设置为true,因为在第一服务器发送树的所有内容到客户端。

回答

3

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

这是问题所在。

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

  • 简单的解决方案:一旦你把它们放在 树不要修改你的对象。但是如果你确实需要重建整棵树。
  • 更好的解决方案:创建包含的项目,但提供它自己的equals /哈希码 方法代理对象(TreeNode或东西) 。
  • 最佳解决方案: Vaadin将其树修改为像标准java容器那样运行 。就目前而言,这种古怪的 行为没有在javadoc中提到的方法 将会失败。

希望这可以帮助别人。

1

即使Vaadin文档中,它说延迟加载Treenot supported,我设法实现以下延迟加载Hierarchical接口。

在局部结构的所有元素存储(在我的情况下,在HashMaphierarchy),不读元素多次这不工作这是非常重要的。我想是因为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()); 
    } 
}); 


我希望这个例子可以帮助,因为我没有在互联网上找到一个活生生的例子。