1

私は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() {}

})

私の意図を理解していただければ幸いです。ありがとうございました!

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

もしそうなら、あなたは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その後、任意の順序で実行できます。

または、コールバック関数を使用してウィンドウのshowメソッドを呼び出します。

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

ただし、ウィンドウはモーダルではないため、ウィンドウがモーダルであることを確認してください。表示されているグリッドの行をクリックすると、コールバック関数が機能しなくなります。

問題。

ところで、そのようなメカニズムを使用し、ウィンドウに複数のタブがあることに注意してください。たとえば、アクティブなタブとしてAを持つA、B、C。BタブとCタブは、レンダリングされるまでcustomerChangedイベント(顧客IDがない)をリッスンしません。したがって、ウィンドウを最初に開いたときに、AタブonCustomerChangedが呼び出され、AタブはIDを認識しますが、BタブとCタブはそれについて何も認識しません(アクティブ化/開くまでまだレンダリングされていないため、それらのonCustomerChangedイベントリスナーは使用されませんでした)。これがそのようなアプローチの問題です。

すべてのタブがレンダリングされたウィンドウを表示することは機能しますが、レンダリングされたすべてのタブを一度に変更することは最善の方法ではありません。特に、データをロードする各タブに大量のコンポーネントがある場合などです。ユーザーは、たとえば1つのタブのみを必要とする場合があります。何かをするために10の値であり、イベントを発生させる既にレンダリングされたすべてのタブに変更を加えるのはやり過ぎです。

さらに、グリッド内の同じレコードの1つをdblクリックすると、同じIDで同じウィンドウが2回開きます。したがって、イベントを発生させる前に、IDが変更されたかどうかを確認することをお勧めします。

上記の問題を解決するには、タブ内でアクティブ化イベントを使用して、各タブ内に独自のcustomerIDプロパティを使用して、その変更を追跡することをお勧めします。もちろん、現在のIDをウィンドウに渡すメソッドも使用します。このような目的のために、ウィンドウ内を使用するか、ミックスインを使用してタブに汎用機能を提供するために、各タブクラスによって拡張されるベースタブクラスを使用できます。activateさらに、ウィンドウが開かれたとき、または設定されたときにイベントが発生しないため、(前回のウィンドウが開かれたときの)最後のアクティブなタブを保存する場合は、表示されているウィンドウのアクティブな(タブに対して同じ汎用コードを実行する)タブを処理しますタブパネルを使用してウィンドウが表示されるたびにアクティブなタブsetActiveTabメソッドの場合、onShowテンプレートメソッドをオーバーライドするのが最適です。もちろん、追加するイベントリスナーをタブから削除します。

于 2012-06-23T23:37:58.007 に答える