【问题标题】:How to update dojo tree data dynamically如何动态更新道场树数据
【发布时间】:2011-03-23 17:16:29
【问题描述】:

我想知道如何动态更新 dojo.dijit.tree 组件的数据。目前我正在使用 dojo.data.ItemFileReadStore 和 dijit.tree.ForestStoreModel 创建树。创建树后,我想定期用新的 JSON 数据重新加载它。

这就是我现在创建树的方式:

<div dojoType="dojo.data.ItemFileReadStore" jsId="myStore" url=getJSONResult></div>

<div dojoType="dijit.tree.ForestStoreModel" jsId="myModel" store="myStore" query="{type:'cat'}" rootId="myRoot" rootLabel="Data" childrenAttrs="children"></div>

<div dojoType="dijit.Tree" model="myModel" labelAttr="sname" label="Data" />

提前致谢。

【问题讨论】:

    标签: javascript dojo tree


    【解决方案1】:

    明确地说你“不能”,但这并不意味着你不能把东西砍成碎片然后死去。

    refreshTree : function(){
        dijit.byId("myTree").dndController.selectNone(); // As per the answer below     
        // Credit to this discussion: http://mail.dojotoolkit.org/pipermail/dojo-interest/2010-April/045180.html
        // Close the store (So that the store will do a new fetch()).
        dijit.byId("myTree").model.store.clearOnClose = true;
        dijit.byId("myTree").model.store.close();
    
        // Completely delete every node from the dijit.Tree     
        dijit.byId("myTree")._itemNodesMap = {};
        dijit.byId("myTree").rootNode.state = "UNCHECKED";
        dijit.byId("myTree").model.root.children = null;
    
        // Destroy the widget
        dijit.byId("myTree").rootNode.destroyRecursive();
    
        // Recreate the model, (with the model again)
        dijit.byId("myTree").model.constructor(dijit.byId("myTree").model)
    
        // Rebuild the tree
        dijit.byId("myTree").postMixInProperties();
        dijit.byId("myTree")._load();
    
    },
    

    这将刷新您的树。

    【讨论】:

    • 感谢您的回答莱克斯。您的脚本确实刷新了树渲染。但是,在这个示例中,我无法在其上加载新数据。我已经实现了调用您创建的函数的定期刷新。我的商店将 url 属性设置为包含 JSON 数据的文件名。我正在更改文件上的数据,但树总是呈现初始数据。你知道如何在上面加载新数据吗?
    • 抱歉 TheLostGuy,我假设您的商店设置为关闭时刷新。添加这个:dijit.byId("myTree").model.store.clearOnClose = true;
    【解决方案2】:

    这是通过商业网站的预生产测试发现的 Layke 解决方案的一个问题(否则它确实有效)。

    案例一:

    • 创建并填充树。
    • 单击要选择的节点。
    • 按照 Layke 的解决方案执行 refreshTree。
    • 单击一个节点,出现错误“this.labelNode is undefined”。

    现在重新开始,案例 2:

    • 创建并填充树。
    • 单击要选择的节点。
    • 按住Ctrl 键单击先前选择的节点。
    • 按照 Layke 的解决方案执行 refreshTree。
    • 点击一个节点,没有错误。

    存储的对第一个选择的选择引用正在用于撤消 进行第二次选择时的选择属性(背景颜色等)。 不幸的是,引用的对象现在在位桶中。修改后的代码 似乎已准备好生产,即没有通过任何生产前测试。

    解决办法是放:

    Tree.dndController.selectNone();
    

    在上面Layke的refreshTree解决方案的第一行之前。

    响应元建议,这里是:

    refreshTree : function() {
        // Destruct the references to any selected nodes so that 
        // the refreshed tree will not attempt to unselect destructed nodes
        // when a new selection is made.
        // These references are contained in Tree.selectedItem,
        // Tree.selectedItems, Tree.selectedNode, and Tree.selectedNodes.
        Tree.dndController.selectNone();
    
        Tree.model.store.clearOnClose = true;
        Tree.model.store.close();
    
        // Completely delete every node from the dijit.Tree     
        Tree._itemNodesMap = {};
        Tree.rootNode.state = "UNCHECKED";
        Tree.model.root.children = null;
    
        // Destroy the widget
        Tree.rootNode.destroyRecursive();
    
        // Recreate the model, (with the model again)
        Tree.model.constructor(dijit.byId("myTree").model)
    
        // Rebuild the tree
        Tree.postMixInProperties();
        Tree._load();
    
    }
    

    【讨论】:

      【解决方案3】:

      感谢这个功能,在我的树中效果很好。

      给刚接触dojo的人(比如我)的一个通知……树创建后,需要用刷新功能扩展树:

      dojo.extend(dijit.Tree, {
          refresh: function() {
              this.dndController.selectNone();
              //...
          }
      });
      

      然后你可以调用函数:

      dijit.byId('myTree').refresh();
      

      【讨论】:

        【解决方案4】:

        更新您的商店将自动更新您的树!

        1. 您需要一个 FileWriteStore,它使您能够修改数据。
        2. 使用商店通过查询获取要更新的项目。
        3. 更新每个返回的项目。
        4. 然后保存存储,树将更新。

          FileWriteStore.fetch({
              query: { color: "red" },
              onComplete: function(items){
                  for (var i = 0; i < items.length; i++){
                      FileWriteStore.setValue(items[i], "color", "green");
                  }
                  FileWriteStore.save();              
              }
          });
          

        【讨论】:

          【解决方案5】:

          Layke 的解决方案对我不起作用。我正在使用道场 1.9.1。我的商店是“ItemFileWriteStore”类型和“TreeStoreModel”类型的模型。

          myStore = new ItemFileWriteStore({
              url : "../jaxrs/group/tree"
          });
          
          itemModel = new TreeStoreModel({
              store : myStore,
              query : {
                  id : "0"
              }
          });
          parser.parse();
          

          这对我有用:

          var tree = dijit.byId('myTree');
          tree.dndController.selectNone(); 
          tree._itemNodesMap = {};
          tree.model.root = null;
          tree.model.store.clearOnClose = true;
          tree.model.store.urlPreventCache = true;
          tree.model.store.revert(); 
          tree.model.store.close();
          tree.rootNode.state = "UNCHECKED";
          if (tree.rootNode) {
              tree.rootNode.destroyRecursive();
          }
          tree.postMixInProperties();
          tree._load();
          

          【讨论】:

            【解决方案6】:

            在查看这些答案时,我已经构建了自己的方法来一次更新特定节点,并且不需要刷新。

            _refreshNodeMapping: function (newNodeData) {
            
                if(!this._itemNodesMap[newNodeData.identity]) return;
            
                var nodeMapToRefresh = this._itemNodesMap[newNodeData.identity][0].item;
                var domNode = this._itemNodesMap[newNodeData.identity][0].domNode;
            
                //For every updated value, reset the old ones
                for(var val in newNodeData)
                {
                    nodeMapToRefresh[val] = newNodeData[val];
            
                    if(val == 'label')
                    {
                        domNode.innerHTML = newNodeData[val];
                    }
                }  
            }
            

            【讨论】:

              【解决方案7】:

              目前不支持。见here

              【讨论】:

              • 感谢您的回复安迪。您知道可以动态更新的替代树吗?
              • Dojo 中没有 - 但其他工具包可能会提供此功能。我在 Dojo 中所做的是在整个树上放置一个 dojox.widget.Standby 小部件(加载图标微调器),然后简单地销毁树并将新树绑定到新商店(或重新填充的商店)。
              猜你喜欢
              • 1970-01-01
              • 2011-11-02
              • 1970-01-01
              • 2014-09-08
              • 1970-01-01
              • 2015-01-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多