2011-03-23 96 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]; 
     } 
    } 
}