我是 extJS 的新手,也许我只是不知道正确的策略,所以如果你愿意,你可以告诉我更好的解决方案。
我正在尝试: 我有一个 extJS 网格。双击时,会出现一个 ExtJS 窗口容器(用于详细设置),其中包含多个选项卡。窗口有一个函数来设置被点击元素的ID。窗口中的每个选项卡也需要此 ID。因此,当窗口容器中的 ID 发生更改时,我想通过事件通知每个选项卡容器有关更改的 ID。
我的问题是,我无法从选项卡访问该窗口来添加监听器,因为该窗口只有在第一次打开时才会呈现。
如果您查看我的源代码,也许您可以更好地理解我的问题:
窗口 (双击网格元素时调用 setCustomerId() 和 show())
Ext.define('myApp.path.view.Edit', {
extend: 'Ext.window.Window',
alias: 'widget.myEdit',
title: 'Edit',
height: 500,
width: 1000,
layout: 'fit',
closeAction: 'hide',
/**
* Initialize my custom event
*/
initComponent: function() {
this.addEvents('customerChanged');
this.callParent();
},
/**
* Sets the current customerId and fires a customerChanged event
* @param {Number} customerId
*/
setCustomerId: function(customerId) {
this.customerId = customerId;
this.fireEvent('customerChanged', this.customerId);
},
/**
* create a container for the editor tabs
*/
items: [{
xtype: 'tabpanel',
items: [
{
xtype: 'myTab'
}
]
}]
})
示例选项卡
Ext.define('myApp.path.view.myTab', {
extend: 'Ext.container.Container',
alias: 'widget.myTab',
title: 'Customer',
layout: 'fit',
/**
* Listen to my custom event
* PROBLEM: works, but only after the window has been displayed one time
*/
afterRender: function() {
this.findParentByType('window').addListener("customerChanged", this.onCustomerChanged)
this.callParent();
},
/**
* Listen to my custom event
* PROBLEM: doesn't work, findParentByType('window') is undefined
*/
initComponent: function() {
this.findParentByType('window').addListener("customerChanged", this.onCustomerChanged)
this.callParent();
},
onCustomerChanged: functio() {}
})
希望你能明白我的用意。 谢谢!
最佳答案
不知道网格的 itemdblclick
事件的代码(这会很有帮助),但我看到它是这样的:
itemdblclick: function(v, m) {
var id = m.get('id');
//think you are not created a window each time, having the "closeAction: 'hide'" in the code
//if for simplicity sake, for sure it should not be here
if (!this.detailsWin) {
this.detailsWin = Ext.create('myApp.path.view.Edit');
}
//you set the ID and after it shows the window
//that is why for the first time event listener is bot working
this.detailsWin.setCustomerId(id);
//showing the window
this.detailsWin.show();
}
如果是这样,则需要在show
之后调用setCustomerId
:
this.detailsWin.show();
this.detailsWin.setCustomerId(id);
或者简单地覆盖窗口内的模板方法:
/**
* @template
*/
onShow: function() {
//firing the event
//should be checking here if the ID was really changed
this.fireEvent('customerChanged', this.customerId);
//call parent to show the window
this.callParent(arguments);
}
然后您可以按任意顺序运行 show
setCustomerId
。
或者用回调函数调用window的show方法:
this.detailsWin.show(null, function(){
this.setCustomerId(id);
});
但请确保该窗口是模态窗口,因为该窗口不是模态窗口,并且显示您将单击网格的行并将其打开,回调函数将不起作用。
问题。
顺便说一句,您应该注意到使用这种机制并且窗口中有多个选项卡。
例如 A、B、C,其中 A 作为事件选项卡。 B 和 C 选项卡在渲染之前不会监听 customerChanged 事件(没有客户 ID)。因此,当第一次打开窗口时,将调用 A 选项卡的 onCustomerChanged ,并且 A 选项卡将知道 ID,但 B 和 C 选项卡对此一无所知(因为它们尚未渲染)直到您激活/打开它们并且它们的 onCustomerChanged
事件监听器未被使用)。这就是这种方法的问题。
显示呈现所有选项卡的窗口将可以工作,但对所有呈现的选项卡进行更改并不是最好的方法,特别是每个选项卡上都有大量组件加载数据等。例如,用户可能需要只有 10 个选项卡中的一个可以执行某些操作,对触发事件的所有已渲染选项卡进行更改就太过分了。
另外,双击网格中的同一记录将使用相同的 ID 打开同一窗口 2 次 - 因此最好在触发事件之前检查 ID 是否已更改。
为了解决上述问题,我建议使用 activate选项卡内的事件在每个选项卡内都有自己的 customerID 属性,用于跟踪其更改,当然还有一个将当前 ID 传递到窗口的方法。为此,您可以使用由每个选项卡类扩展的基选项卡类,在窗口内部使用或使用 mixin 来为选项卡提供通用功能。
如果您想保存最后一个事件选项卡(从上一次窗口打开时开始),请加上处理显示窗口上的事件选项卡(为选项卡运行相同的通用代码)选项卡,因为不会触发 activate
事件当窗口打开或每次使用 tabpanel setActiveTab
方法显示窗口时设置事件选项卡时,最好的地方是重写 onShow 模板方法。
当然,从选项卡中删除添加事件监听器。
关于javascript - 让子元素监听 extJS 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11156851/