在 qooxdoo 中自定义 virtualTree 无法按预期工作

customizing virtualTree in qooxdoo doesn't work as expected

我正在使用 qooxdoo 构建自定义 virtualTree,在我 open/close/reopen 一个节点之前,它可以正常工作。 那就一团糟了。我不知道我错过了哪一部分。

这是一个代码示例: virtual tree

要复制,请打开一个节点(例如"Dep1")。你可以悬停孩子,一切都很好。现在关闭节点并重新打开它。现在节点中的图标发生了变化,节点有悬停效果,这在我们最初打开它时不是这样的。

我是不是漏掉了什么?

此致

代码如下:

var data = {
 "label": "ROOT",
 
 "children" : [
    {
      "LDEP" : "Dep1",
      "children" : [
        {
          "CVEH" : 1,
          "LVEH" : "veh1_1"
        },
        {
          "CVEH" : 2,
          "LVEH" : "veh1_2"
        }
      ]
    },
    
    {
      "LDEP" : "Dep2",
      "children" : [
        {
          "CVEH" : 3,
          "LVEH" : "veh2_1"
        },
        {
          "CVEH" : 4,
          "LVEH" : "veh2_2"
        }
      ]
    },
    
  ]
  
};
var model = qx.data.marshal.Json.createModel(data, false);
var vtree = new qx.ui.tree.VirtualTree(model, "children", "children");

this.getRoot().add(vtree,
{
  left : 100,
  right : 100,
  top  : 50
});

vtree.set({
 showTopLevelOpenCloseIcons : true,
 hideRoot : true,
 backgroundColor : "gray"
});
   
/* label options */
vtree.setLabelOptions({
    converter : function(value, model)
    {
     if (value){ 
      return  "<b>" + model.get("LDEP") + "</b>";
     }
     else
     { 
      return model.get("LVEH");
     }
    }
});
       

/* 
 * icon options, if a dep then return a generic symbol else return 
 * vehicle icon
 */
vtree.setIconPath("children");
vtree.setIconOptions({
  converter : function(value, model)
  {
   if (value){
    return "icon/22/mimetypes/text-html.png";
   }
   else
   { 
    return "icon/22/mimetypes/media-image.png"
   }
  }
});


var delegate = {
    bindItem : function(controller, item, index)
    {
      controller.bindDefaultProperties(item, index);
      
      //set icon size to 24x24 for leaves
      var icon = item.getChildControl("icon");
      if(item.getModel().getChildren){
       //dept
       item.setBackgroundColor("gray");
      } else {
       //vehicle
       item.setBackgroundColor("white");
       icon.set({
        width  : 32,
        height  : 32,
        scale : true,
        marginTop : -4
       });
      }
  
      //labels, accept html
      var lbl = item.getChildControl("label");
      lbl.set({
       rich : true,
       textColor : "black"
      });
  
      //change color on pointerin and pointerout of vehicles
      if (!item.getModel().getChildren){
       item.addListener("pointerover", function(){
        item.getChildControl("label").fadeIn(100);
        item.setBackgroundColor("blue");
        item.getChildControl("label").setTextColor("orange");
       });
       
       item.addListener("pointerout", function(){
        item.setBackgroundColor("white");
        item.getChildControl("label").setTextColor("black");
       });
      }
    },
    
    /* 
     * sorting
     */ 
    sorter : function(a, b){
     var A = (a.getChildren? a.get("LDEP") : a.get("LVEH")).toUpperCase(), 
        B = (b.getChildren? b.get("LDEP") : b.get("LVEH")).toUpperCase(); 
      
     return A > B ? 1 : A < B ? -1 : 0; 
    }
};
  
vtree.setDelegate(delegate);

要了解您观察到的效果,需要了解虚拟小部件在 qooxdoo 中的工作原理。

虚拟小部件意味着您可以显示大量数据,只需要几个小部件呈现可见内容。想象一棵树有数百个节点和子节点,但一次只有 10 个节点可见。然后,虚拟小部件根据需要实例化尽可能多的真实小部件,并重新使用这些小部件来显示树的可见部分。

显示节点和树叶的虚拟树小部件通过更改小部件的模型及其外观来重用实例化的小部件。这样一来,在用户交互时,虚拟树节点可能会由以前显示叶子的项目呈现。

所有这些都是通过委托 bindItem 成员函数完成的,每次将真实小部件重新用于虚拟项目时都会调用该函数。因此,在 bindItem 中添加事件侦听器会将后续越来越多的事件侦听器添加到单个小部件 tree/leaf 实例,显示您描述的效果。

要实现您想要的效果,您必须将您的逻辑添加到 configureItem 委托成员中,该成员仅在树项小部件实例化时调用一次。在那里你必须区分当前显示节点或叶子的项目,你可以通过 item.getAppearance() 获取该项目的当前外观来简单地完成。叶子的结果将是 virtual-tree-file,节点的结果将是 virtual-tree-folder

pointeroverpointerout 添加的事件侦听器应根据外观添加所需的样式。

请注意,所有这些最好由自定义外观主题处理,您可以在其中添加基于小部件状态(如悬停)使用的大多数样式,此外还有带有淡入标签的标签子控件的动画。

请将以下要点粘贴到 qooxdoo 游乐场,我在其中创建了一个演示上述所有演讲的示例:

https://gist.github.com/level420/ba4e25f98618064f91f5aa6cb6bb1124