extjsextjs4.2extjs6-classic

ExtJS Tree checkchange listener does not display mask


I have a Ext Tree with checkboxes and when any checkbox is clicked, it will kick off a process that could take an arbitrary amount of time. For this to be more user friendly, I would like to add a load mask to the tree. However, when the listener function is entered, the UI locks up and does not update until the listener function finishes. The issue occurs in ExtJs 4.2 - 7.5 classic.

If I add a "setTimeout()" after the mask that contains the processing code, or set a breakpoint after the mask, the mask will display. The problem with this is the setTimeout() function does not seem to be supported in IE.

Here's a fiddle with example code, the processing function just factors a very large number in order to simulate processing time - https://fiddle.sencha.com/#view/editor&fiddle/3hl2

Here's the actual code:

Ext.application({
    name: 'ExtTest',
    launch: function () {
        Ext.create('ExtTest.view.Viewport');
    }
});

Ext.define('ExtTest.view.Viewport', {
    extend: 'Ext.container.Viewport',
    initComponent: function () {
        this.items = [{
            xtype: 'treetest'
        }]
        this.callParent();
    }
});

Ext.define('ExtTest.view.TreeTest', {
    extend: 'Ext.tree.Panel',
    alias: 'widget.treetest',
    height: '100%',
    width: '100%',

    initComponent: function () {
        console.log('Creating tree');
        var me = this;
        var store = Ext.create('Ext.data.TreeStore', {
            fields: ['text'],
            root: {
                text: 'root',
                expanded: true,
                children: me.getTreeData()
            }

        })

        Ext.applyIf(this, {
            store: store,
            columns: [{
                width: "100%",
                xtype: 'treecolumn',
                dataIndex: 'text'
            }],
            listeners: {
                checkchange: function () {
                    me.getEl().mask('loading');
                    me.factorNumber(500000000);
                    me.getEl().unmask();
                }
            }
        });

        this.callParent();
    },

    factorNumber: function (aNumber) {
        for (var i = 1; i <= aNumber; i++) {
            if (aNumber % i === 0) {
                console.log(i);
            }
        }
    },

    getTreeData: function () {
        return [{
            text: 'child 1',
            leaf: true,
            checked: false
        }, {
            text: 'child 2',
            leaf: true,
            checked: false
        }, {
            text: 'child 3',
            leaf: true,
            checked: false
        }];
    }
});


Solution

  • Your Problem is, that your function eats up all resources before the dom can be updated.

    Solution would be to give the loading mask time to show up and then start your calculation.

                   checkchange: function () {
                        me.getEl().mask('loading');
                        Ext.defer(function() {
                            me.factorNumber(500000000);
                            me.getEl().unmask();
                        }, 50);
                    }