应用 "scrollTo" 的正确事件以显示动态添加的嵌套面板
The right event to apply "scrollTo" to show a dynamically added nested panel
我在 ExtJS6 现代(移动)应用程序中有一个只能垂直滚动的面板。子面板是动态添加的。添加新的子面板后,我需要将面板滚动到末尾,以使其可见。这是使用以下行完成的:
Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);
我在单击按钮时执行了这一行,它起作用了(但需要手动单击按钮)。我试图找到合适的事件,我可以在其中添加此行以自动执行滚动,但没有成功。我几乎尝试了子面板所有可能的相关事件:show, add, added, activate, ...我也尝试了父面板的事件没有成功。
显然,这些事件发生在父面板的滚动器考虑添加的子面板之前,因此它滚动到最后一个子面板。我在这里闻到了异步行为。证明是我在延迟 0.5 秒的任务中调用 scrollTo
方法并且它有效。但是这个解决方案并不可靠。
问题是:这行代码应该放在哪里(在哪个组件的哪个事件中)才能正确地将父级滚动到其末尾?
[编辑]
这是问题的部分代码。首先,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>'
}
]
});
这是将父面板 tabmainMessagesPanel
滚动到末尾以显示新添加的消息的延迟任务:
Ext.define('MyApp.view.main.Global', {
statics: {
scroller: Ext.create('Ext.util.DelayedTask', function() {
Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);
})
}
}
现在,包含将包含消息的面板 tabmainMessagesPanel
的选项卡面板:
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
}
});
最后,这是控制器中的一个事件,它会在新消息到达时创建消息并将其添加到 tabmainMessagesPanel
:
handle_message: function (mess) {
var p = Ext.create('MyApp.view.message.Message', {
mBody : mess.body
});
Ext.getCmp('tabmainMessagesPanel').add(p);
}
这里是这个问题的答案。 6个月后我找到了它。我post在这里是为了那些可能有同样问题的人的利益。
解决办法是定义面板tabmainMessagesPanel
的滚动条的事件refresh
,在里面滚动到最后。所以,面板的定义tabmainMessagesPanel
变成:
{
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'
}
我在 ExtJS6 现代(移动)应用程序中有一个只能垂直滚动的面板。子面板是动态添加的。添加新的子面板后,我需要将面板滚动到末尾,以使其可见。这是使用以下行完成的:
Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);
我在单击按钮时执行了这一行,它起作用了(但需要手动单击按钮)。我试图找到合适的事件,我可以在其中添加此行以自动执行滚动,但没有成功。我几乎尝试了子面板所有可能的相关事件:show, add, added, activate, ...我也尝试了父面板的事件没有成功。
显然,这些事件发生在父面板的滚动器考虑添加的子面板之前,因此它滚动到最后一个子面板。我在这里闻到了异步行为。证明是我在延迟 0.5 秒的任务中调用 scrollTo
方法并且它有效。但是这个解决方案并不可靠。
问题是:这行代码应该放在哪里(在哪个组件的哪个事件中)才能正确地将父级滚动到其末尾?
[编辑]
这是问题的部分代码。首先,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>'
}
]
});
这是将父面板 tabmainMessagesPanel
滚动到末尾以显示新添加的消息的延迟任务:
Ext.define('MyApp.view.main.Global', {
statics: {
scroller: Ext.create('Ext.util.DelayedTask', function() {
Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);
})
}
}
现在,包含将包含消息的面板 tabmainMessagesPanel
的选项卡面板:
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
}
});
最后,这是控制器中的一个事件,它会在新消息到达时创建消息并将其添加到 tabmainMessagesPanel
:
handle_message: function (mess) {
var p = Ext.create('MyApp.view.message.Message', {
mBody : mess.body
});
Ext.getCmp('tabmainMessagesPanel').add(p);
}
这里是这个问题的答案。 6个月后我找到了它。我post在这里是为了那些可能有同样问题的人的利益。
解决办法是定义面板tabmainMessagesPanel
的滚动条的事件refresh
,在里面滚动到最后。所以,面板的定义tabmainMessagesPanel
变成:
{
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'
}