私は最近ExtJSの学習を始めましたが、イベントの処理方法を理解するのに苦労しています。 ExtJSの以前のバージョンの経験はありません。
さまざまなマニュアル、ガイド、およびドキュメントのページを読んで、その使用方法を理解しましたが、どのように機能するのか明確ではありません。古いバージョンのExtJS向けのチュートリアルをいくつか見つけましたが、ExtJS 4でそれらがどのように適用できるかわかりません。
特に次のような「最終単語」を探しています。
たとえば、 この質問 は、イベントハンドラーが非常に多くの引数を受け取ることができると信じさせます。ハンドラへの引数が2つしかない他のチュートリアルを見てきました。何が変わりますか?
DOM要素のイベント処理を説明することから始めましょう。
まず、DOMノードを直接操作したくないでしょう。代わりに、おそらく Ext.Element
インターフェイスを利用したいと思うでしょう。イベントハンドラーを割り当てるために、 Element.addListener
および Element.on
(これらは同等)が作成されました。したがって、たとえば、htmlがある場合:
<div id="test_node"></div>
click
イベントハンドラーを追加します。Element
を取得しましょう:
var el = Ext.get('test_node');
では、 click
イベントのドキュメントを確認しましょう。ハンドラーには3つのパラメーターがあります。
click(Ext.EventObject e、HTMLElement t、Object eOpts)
ハンドラーを割り当てることができるこれらすべてを知っている:
// event name event handler
el.on( 'click' , function(e, t, eOpts){
// handling event here
});
ウィジェットのイベント処理は、DOMノードのイベント処理とほとんど同じです。
まず、ウィジェットのイベント処理は、 Ext.util.Observable
mixinを使用して実現されます。イベントを適切に処理するには、ウィジェットにExt.util.Observable
をミックスインとして含める必要があります。すべての組み込みウィジェット(パネル、フォーム、ツリー、グリッドなど)には、デフォルトでミックスインとしてExt.util.Observable
があります。
ウィジェットには、ハンドラーを割り当てる2つの方法があります。最初の1つは、 on メソッド(またはaddListener
)を使用することです。たとえば、Button
ウィジェットを作成して、click
イベントを割り当てましょう。まず、イベントのドキュメントでハンドラーの引数を確認する必要があります。
click(Ext.button.Button this、Event e、Object eOpts)
では、on
を使用してみましょう。
var myButton = Ext.create('Ext.button.Button', {
text: 'Test button'
});
myButton.on('click', function(btn, e, eOpts) {
// event handling here
console.log(btn, e, eOpts);
});
2番目の方法は、ウィジェットの listeners configを使用することです。
var myButton = Ext.create('Ext.button.Button', {
text: 'Test button',
listeners : {
click: function(btn, e, eOpts) {
// event handling here
console.log(btn, e, eOpts);
}
}
});
Button
ウィジェットは特別な種類のウィジェットであることに注意してください。 handler
configを使用して、このウィジェットにクリックイベントを割り当てることができます。
var myButton = Ext.create('Ext.button.Button', {
text: 'Test button',
handler : function(btn, e, eOpts) {
// event handling here
console.log(btn, e, eOpts);
}
});
まず、 addEvents メソッドを使用してイベントを登録する必要があります。
myButton.addEvents('myspecialevent1', 'myspecialevent2', 'myspecialevent3', /* ... */);
addEvents
メソッドの使用はオプションです。このメソッドへのコメントにあるように、このメソッドを使用する必要はありませんが、イベントのドキュメントの場所を提供します。
イベントを発生させるには、 fireEvent メソッドを使用します。
myButton.fireEvent('myspecialevent1', arg1, arg2, arg3, /* ... */);
arg1, arg2, arg3, /* ... */
はハンドラーに渡されます。これで、イベントを処理できます。
myButton.on('myspecialevent1', function(arg1, arg2, arg3, /* ... */) {
// event handling here
console.log(arg1, arg2, arg3, /* ... */);
});
addEvents メソッド呼び出しを挿入するのに最適な場所は、新しいウィジェットを定義するときにウィジェットのinitComponent
メソッドであることに言及する価値があります。
Ext.define('MyCustomButton', {
extend: 'Ext.button.Button',
// ... other configs,
initComponent: function(){
this.addEvents('myspecialevent1', 'myspecialevent2', 'myspecialevent3', /* ... */);
// ...
this.callParent(arguments);
}
});
var myButton = Ext.create('MyCustomButton', { /* configs */ });
バブリングを防ぐには、return false
または Ext.EventObject.preventDefault()
を使用します。ブラウザのデフォルトのアクションを防ぐには、 Ext.EventObject.stopPropagation()
を使用します。
たとえば、ボタンにクリックイベントハンドラーを割り当てましょう。左ボタンがクリックされていない場合、デフォルトのブラウザアクションを防止します。
myButton.on('click', function(btn, e){
if (e.button !== 0)
e.preventDefault();
});
上記の非常に優れた答えに加えて、コントローラー間の通信を可能にするMVCセットアップで非常に役立つアプリケーション全体のイベントについて言及したいと思います。 (extjs4.1)
選択ボックスを備えたコントローラーステーション(Sencha MVCの例)があるとします。
Ext.define('Pandora.controller.Station', {
extend: 'Ext.app.Controller',
...
init: function() {
this.control({
'stationslist': {
selectionchange: this.onStationSelect
},
...
});
},
...
onStationSelect: function(selModel, selection) {
this.application.fireEvent('stationstart', selection[0]);
},
...
});
選択ボックスが変更イベントをトリガーすると、関数onStationSelect
が起動されます。
その関数内で次を確認します。
this.application.fireEvent('stationstart', selection[0]);
これにより、他のコントローラーからリッスンできるアプリケーション全体のイベントが作成および起動されます。
したがって、別のコントローラーでは、ステーション選択ボックスがいつ変更されたかを知ることができます。これは、次のようにthis.application.on
をリッスンすることで実行されます。
Ext.define('Pandora.controller.Song', {
extend: 'Ext.app.Controller',
...
init: function() {
this.control({
'recentlyplayedscroller': {
selectionchange: this.onSongSelect
}
});
// Listen for an application wide event
this.application.on({
stationstart: this.onStationStart,
scope: this
});
},
....
onStationStart: function(station) {
console.info('I called to inform you that the Station controller select box just has been changed');
console.info('Now what do you want to do next?');
},
}
Selectboxが変更された場合、コントローラーonStationStart
の関数Song
も起動します...
Sencha docsから:
アプリケーションイベントは、多くのコントローラーを持つイベントに非常に役立ちます。これらの各コントローラーで同じビューイベントをリッスンする代わりに、1つのコントローラーのみがビューイベントをリッスンし、他のコントローラーがリッスンできるアプリケーション全体のイベントを起動します。これにより、コントローラーは互いの存在を知らずに、または依存せずに互いに通信できます。
私の場合:ツリーノードをクリックして、グリッドパネルのデータを更新します。
以下のコメントから@ gm2008のおかげで2016を更新します:
アプリケーション全体のカスタムイベントの発生に関しては、ExtJS V5.1が公開された後、Ext.GlobalEvents
を使用する新しいメソッドがあります。 。
イベントを発生させるとき、次を呼び出すことができます:Ext.GlobalEvents.fireEvent('custom_event');
イベントのハンドラーを登録するとき、次を呼び出します:Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope);
この方法はコントローラーに限定されません。任意のコンポーネントは、コンポーネントオブジェクトを入力パラメータースコープとして配置することにより、カスタムイベントを処理できます。
コントローラーイベントリスナーのもう1つのトリック。
ワイルドカードを使用して、任意のコンポーネントからのイベントを監視できます。
this.control({
'*':{
myCustomEvent: this.doSomething
}
});
上記の優れた回答にペンスを2つ追加したかっただけです。Extjs4.1より前のバージョンで作業していて、アプリケーション全体のイベントはなくても必要な場合は、非常に簡単なテクニックを使用して、 Observableを拡張する単純なオブジェクトで、アプリ内で必要なイベントを定義します。次に、実際のhtml dom要素を含むアプリの任意の場所からこれらのイベントを起動し、そのコンポーネントから必要な要素を中継することにより、任意のコンポーネントからそれらをリッスンできます。
Ext.define('Lib.MessageBus', {
extend: 'Ext.util.Observable',
constructor: function() {
this.addEvents(
/*
* describe the event
*/
"eventname"
);
this.callParent(arguments);
}
});
次に、他のコンポーネントから次のことができます。
this.relayEvents(MesageBus, ['event1', 'event2'])
そして、それらを任意のコンポーネントまたはdom要素から起動します:
MessageBus.fireEvent('event1', somearg);
<input type="button onclick="MessageBus.fireEvent('event2', 'somearg')">
質問の一部でなくても、知っておくと便利なことがもう2つあります。
relayEvents
メソッドを使用すると、別のコンポーネントの特定のイベントをリッスンするようにコンポーネントに指示し、最初のコンポーネントから発生したかのようにそれらを再度発生させることができます。 APIドキュメントは、ストアload
イベントを中継するグリッドの例を提供します。いくつかのサブコンポーネントをカプセル化するカスタムコンポーネントを作成するときに非常に便利です。
別の方法、つまり、カプセル化コンポーネントmycmp
が受信したイベントをそのサブコンポーネントsubcmp
の1つに渡す方法は、次のように実行できます。
mycmp.on('show' function (mycmp, eOpts)
{
mycmp.subcmp.fireEvent('show', mycmp.subcmp, eOpts);
});