我是extJS的新手,也许我只是不知道正确的策略,所以如果你愿意,你可以告诉我一个更好的解决方案。
我在尝试什么: 我有一个extJS网格。在双击时,应显示ExtJS Window容器(用于详细设置),其中包含多个选项卡。该窗口具有设置被点击元素的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() {}
})
我希望你能理解我的意图。 谢谢!
答案 0 :(得分:0)
不知道网格的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();
}
如果是这样,您需要在setCustomerId
之后调用show
:
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的标签可以做一些事情,对所有已经渲染的标签进行更改是很难的。
再加上dbl点击一个网格中相同的记录,将使用相同的ID打开同一个窗口2次 - 所以最好在触发事件之前检查ID是否已更改。
为了解决上述问题,我建议在每个选项卡内部的选项卡中使用activate事件,它自己的customerID属性用于跟踪它的更改,当然还有一个获取传递给窗口的当前ID的方法。为此,您可以使用在窗口内使用每个选项卡类扩展的基本选项卡类,或使用mixin为选项卡提供通用功能。
如果要保存最后一个活动选项卡(从上一个时间窗口打开),则在正在显示的窗口上处理活动(运行相同的选项卡通用代码)选项卡,因为activate
事件在窗口时不会被触发每次使用tabpanel setActiveTab
方法显示窗口时,都会打开或只设置活动选项卡,最好的位置是覆盖onShow模板方法。
当然,从选项卡中删除添加事件侦听器。