extjssencha-touchsencha-touch-2.1extjs6-modern

The right event to apply "scrollTo" to show a dynamically added nested panel


I have a panel in ExtJS6 modern (mobile) application that can scroll vertically only. Sub panels are added dynamically to it. I need to scroll the panel to its end after adding a new sub-panel in order to make it visible. This is done using this line:

Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);

I execute this line in a button click, and it works (but need to click the button manually). I tried to find the right event where I can add this line to do the scroll automatically, without success. I nearly tried all the possible relevant events of the sub-panel: show, add, added, activate, ... I also tried the events of the parent panel without success.

Apparently, these events happen before the scroller of the parent panel takes into account the added sub-panel, so it scrolls to the before-last one. I smell asynchronous behavior here. The proof is that I call the scrollTo method in a delayed task of 0.5 second and it works. But this solution is not reliable.

The question is: where (in which event of which component) this line of code should go in order to scroll the parent to its end correctly?

[EDIT]

Here is the part of the code concerning the question. First, the Message class:

Ext.define('MyApp.view.message.Message', {
    extend : 'Ext.Panel', 
    xtype : 'message',

    layout : 'hbox',
    config : {
        mBody : ''
    },

    listeners: {
        added: function (element) {
            MyApp.view.main.Global.scroller.delay(500); //start a delayed task to scroll parent panel
        }
    }, 

    items: [
                {
                    flex : 1
                },
                {
                    maxWidth: '80%',
                    width: 'auto',
                    html : '<div class="myClass">' + this.getMBody() + '</div>'
                }
    ]
});

Here is the delayed task that scrolls the parent panel tabmainMessagesPanel to its end in order to show the newly-added message:

Ext.define('MyApp.view.main.Global', {
    statics: {
        scroller: Ext.create('Ext.util.DelayedTask', function() {
         Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);  
        })
    }
}

Now, the tab panel that contains the panel tabmainMessagesPanel that will contain the messages:

Ext.define('MyApp.view.main.TabMain', {
extend : 'Ext.tab.Panel',
mixins : [ 'Ext.mixin.Responsive' ],
xtype : 'tabmain',

responsiveConfig : {
    portrait : {
        items : 
        [ 
        {
            title : 'Messages',
            layout : 'vbox',

            items : [ {
                xtype: 'panel',
                layout : 'vbox',
                height: '100%',
                id: 'tabmainMessagesPanel',
                scrollable : 'vertical',
                style : 'background-color:#F0F0F0'
            },
            {
                xtype : 'inputfield',
                docked : 'bottom'
            }]
        }, 
        {
            title : 'Connect',
            layout: 'vbox',
            items : [
                  //some UI elements
            ]
        }
        ]
    },

    //--------------------------------------------------

    landscape : {
        // same as portrait
    }
},

//--------------------------------------------------

controller : 'tabmain',
viewModel : 'tabmain',

defaults : {
    tab : {
        iconAlign : 'top'
    },
    styleHtmlContent : true
}

});

Finally, this is an event in a controller that creates and adds a message to tabmainMessagesPanel whenever a new message arrives:

handle_message: function (mess) {
     var p = Ext.create('MyApp.view.message.Message', {
          mBody : mess.body
        });
    Ext.getCmp('tabmainMessagesPanel').add(p);
}

Solution

  • Here is the answer for this. I found it 6 months later. I post it here for the benefit of those who may have the same issue.

    The solution is to define the event refresh of the scroller of the panel tabmainMessagesPanel, and scroll to the end in it. So, the definition of the panel tabmainMessagesPanel becomes:

            {
                xtype: 'panel',
                layout : 'vbox',
                height: '100%',
                id: 'tabmainMessagesPanel',
                scrollable : 'vertical',
                listeners: {
                    initialize: function (me) {
                        me.getScrollable().on('refresh', function () {
                            me.getScrollable().scrollTo(Infinity, Infinity, true);
                        }); 
                    }
                },
                style : 'background-color:#F0F0F0'
            }