Search code examples
javascripttreedojotreeviewdijit.tree

Dojo 1.10 - refresh Tree view while keeping expanded nodes states


I have a Dojo tree in which I change icons depending on item values with the getIconClass method:

_tree = new Tree({
    model: _model,
    getIconClass: function(item) {
        if (item.completed) {
            return "iconCompleted";
        } else if (item.launched) {
            return "iconIncomplete";
        } else {
            return "iconInitial";
        }
    }
}, div_id);

I'm searching a way to refresh the tree view when the item properties change, for now I found this:

refreshTree : function(){
    _tree.rootNode.destroyRecursive();
    _tree.model.constructor(_tree.model)
    _tree.postMixInProperties();
    _tree._load();
}

This function refresh the tree, but it actually rebuild the view, so:

  • The tree makes time to shows up again
  • Expanded nodes states are reinitialized

So my question is : What would be the method to update the tree dynamically instantanly with keeping the expanded node states?

I started writing something to get expanded nodes states, but when I need to set the expanded nodes states again, as the tree view makes time to shows up, I would need a callback to know when tree view is finished to appear, and I didn't found it. BTW is there a propriety to make the tree view appears instantanly?


Solution

  • If you only want to change the icon there is no need to recreate the tree. You can wrap your store with Observable and the tree will be notified when the store data change. To update an item use the store.put() function.

    require([
        "dojo/store/Memory",
        "dojo/store/Observable",
        "dijit/tree/ObjectStoreModel",
        "dijit/Tree",
        "dojo/domReady!"
    ], function(Memory, Observable, ObjectStoreModel, Tree){
    
        myStore = new Memory({
            data: [
            { id: 'world', name:'The earth', type:'planet', population: '6 billion'},
            { id: 'AF', name:'Africa', type:'continent', population:'900 million', area: '30,221,532 sq km',
                    timezone: '-1 UTC to +4 UTC', parent: 'world'},
                { id: 'EG', name:'Egypt', type:'country', parent: 'AF' },
                { id: 'KE', name:'Kenya', type:'country', parent: 'AF' },
                    { id: 'Nairobi', name:'Nairobi', type:'city', parent: 'KE' },
                    { id: 'Mombasa', name:'Mombasa', type:'city', parent: 'KE' },
                { id: 'SD', name:'Sudan', type:'country', parent: 'AF' },
                    { id: 'Khartoum', name:'Khartoum', type:'city', parent: 'SD' },
            { id: 'AS', name:'Asia', type:'continent', parent: 'world' },
                { id: 'CN', name:'China', type:'country', parent: 'AS' },
                { id: 'IN', name:'India', type:'country', parent: 'AS' },
                { id: 'RU', name:'Russia', type:'country', parent: 'AS' },
                { id: 'MN', name:'Mongolia', type:'country', parent: 'AS' },
            { id: 'OC', name:'Oceania', type:'continent', population:'21 million', parent: 'world'},
            { id: 'EU', name:'Europe', type:'continent', parent: 'world' },
                { id: 'DE', name:'Germany', type:'country', parent: 'EU' },
                { id: 'FR', name:'France', type:'country', parent: 'EU' },
                { id: 'ES', name:'Spain', type:'country', parent: 'EU' },
                { id: 'IT', name:'Italy', type:'country', parent: 'EU' },
            { id: 'NA', name:'North America', type:'continent', parent: 'world' },
            { id: 'SA', name:'South America', type:'continent', parent: 'world' }
            ],
            getChildren: function(object){
                // Supply a getChildren() method to store for the data model where
                // children objects point to their parent (aka relational model)
                return this.query({parent: object.id});
            }
        });
        myStore = new Observable(myStore);
        // Create the model
        var myModel = new ObjectStoreModel({
            store: myStore,
            query: {id: 'world'}
        });
    
        // Create the Tree.
        var tree = new Tree({
            model: myModel,
            getIconClass: function(item, opened) {
                if (item.completed) {
                    return "dijitLeaf";
                } else if (item.launched) {
                    return (opened ? "dijitFolderOpened" : "dijitFolderClosed");
                } else {
                    return (opened ? "dijitFolderOpened" : "dijitFolderClosed");
                }
            }
        });
        tree.placeAt("test");
        tree.startup();
    });
    
    function changeOceaniaIcon() {
        var item = myStore.get('OC');
        if (item) {
            item.completed = !item.completed;
            myStore.put(item);
        }
    }
    <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css"> 
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css">
    
    <div class="claro">
      <div id="test"></div>
    <button onclick="changeOceaniaIcon();">
    Change Oceania Icon
    </button>
    </div>