1

我是 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() {}

})

我希望你能明白我的意图。谢谢!

4

1 回答 1

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();    
}

如果是这样,您需要调用setCustomerIdafter 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按任何顺序运行。

或者使用回调函数调用窗口的 show 方法:

this.detailsWin.show(null, function(){ 
    this.setCustomerId(id);
});

但请确保窗口是模态的,因为窗口不是模态的,并且显示您将单击网格的行并打开回调函数将不起作用。

问题。

顺便说一句,您应该注意到使用这种机制并且在窗口中有多个选项卡。例如 A、B、C,将 A 作为活动选项卡。B 和 C 选项卡在呈现之前不会监听 customerChanged 事件(没有客户 ID)。因此,当第一次打开窗口时,onCustomerChanged将调用 A 选项卡,并且 A 选项卡将知道 ID,但 B 和 C 选项卡对此一无所知(因为它们在您激活/打开它们之前尚未呈现,并且他们的onCustomerChanged事件监听器没有被使用)。这就是这种方法的问题。

显示呈现所有选项卡的窗口将起作用,但对所有呈现的选项卡进行更改并不是最好的方法,特别是在每个选项卡加载数据等上有大量组件。例如,用户可能只需要一个选项卡10 做某事,对所有已经呈现的触发事件的选项卡进行更改是过大的。

再加上 dbl 在网格中单击一个相同的记录,将使用相同的 ID 打开相同的窗口 2 次 - 因此最好检查 ID 是否在触发事件之前更改。

为了解决上述问题,我建议在标签内使用激活事件,每个标签内都有自己的 customerID 属性来跟踪它的变化,当然还有一种方法将当前 ID 传递给窗口。为此,您可以使用由每个选项卡类在窗口内部扩展的基本选项卡类,或使用 mixin 为选项卡提供通用功能。如果您想保存最后一个活动选项卡(从上一个时间窗口打开),则处理显示窗口上的活动选项卡(为选项卡运行相同的通用代码)选项卡,因为activate在打开窗口或仅设置时不会触发事件每次使用选项卡面板显示窗口时的活动选项卡setActiveTab方法,最好的地方是重写 onShow 模板方法。当然从选项卡中删除添加事件侦听器。

于 2012-06-23T23:37:58.007 回答