如何动态更新dojo树数据

时间:2011-03-23 17:16:30

标签: javascript dojo tree

我想知道如何动态更新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" />

提前致谢。

7 个答案:

答案 0 :(得分: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 :(得分:9)

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

案例1:

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

现在重新开始,案例2:

  • 创建&amp;填充一棵树。
  • 单击要选择的节点。
  • 按住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();

}

答案 2 :(得分:1)

感谢这个功能,在我的树上很有效。

通知那些不熟悉dojo的人(像我一样)......创建树后,需要使用刷新功能扩展树:

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

然后你可以用以下方法调用该函数:

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

答案 3 :(得分: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();              
        }
    });
    

答案 4 :(得分: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();

答案 5 :(得分: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];
        }
    }  
}

答案 6 :(得分:-1)

目前不支持。请参阅here