2011-03-23 60 views
9

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

这是我此刻创建树:提前

<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" /> 

感谢。

回答

20

明确表示你“不能”,但这并不意味着你不能破解并且无法尝试。

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(); 

}, 

这会刷新你的树。

+1

感谢您的回答Laykes。你的脚本确实刷新了树渲染。但是,在这个例子中,我无法在其上加载新数据。我已经实现了定期刷新,调用你创建的函数。我的商店将url属性设置为包含JSON数据的文件名。我正在更改文件上的数据,但树总是呈现初始数据。你知道如何在其上加载新数据吗? – Zion 2011-03-25 13:10:33

+0

对不起TheLostGuy,我认为你的商店设置为关闭时刷新。添加:dijit.byId(“myTree”)。model.store.clearOnClose = true; – Layke 2011-03-25 15:53:42

+0

非常感谢Laykes。现在这确实对我有用。 干杯! – Zion 2011-04-01 12:38:46

-1

目前不支持。见here

+0

感谢您的回复Andy。你知道一个可以动态更新的替代树吗? – Zion 2011-03-24 17:37:05

+0

不在Dojo中 - 但其他工具包可能会提供此功能。我在Dojo中做的是在整个树上加载一个dojox.widget.Standby小部件(加载图标微调器),并简单地销毁该树并将新树绑定到新的商店(或重新填充的商店)。 – Andy 2011-03-25 14:30:50

9

这是Layke的解决方案(否则工作正常)通过商业网站的预生产测试发现的问题。

案例1:

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

现在重新开始,情况2:

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

存储的对第一个选择的选择引用正在用于在进行第二个选择时撤消选择属性(背景颜色等)。 不幸的是,被引用的对象现在处于比特桶中。修改后的代码 似乎是生产就绪的,即没有任何预生产测试失败。

解决的办法是把:

之前上述Layke的refreshTree溶液的第一线
Tree.dndController.selectNone(); 

针对元的建议,那就是:

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(); 

} 
1

感谢这个功能,我在树的伟大工程。

通知给那些刚刚接触道场的人(像我)......创建树后,需要与刷新功能扩展树:

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

然后你就可以调用函数:

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

更新你的店会自动更新你的树!

  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();    
        } 
    }); 
    
0

Layke的解决方案并没有为我工作。我正在使用dojo 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(); 
0

虽然经历这些问题的答案我已经建立了我自己的方法,在同一时间更新一次特定节点而无需刷新。

_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]; 
     } 
    } 
}