ExtJS 4のイベント処理について説明する


130

私は最近ExtJSの学習を始めており、イベントの処理方法を理解するのに苦労しています。以前のバージョンのExtJSの経験はありません。

さまざまなマニュアル、ガイド、ドキュメントのページを読んで、その使い方を理解しましたが、どのように機能するかはわかりません。ExtJSの古いバージョンのチュートリアルをいくつか見つけましたが、それらがExtJS 4にどのように適用できるかわかりません。

具体的には、次のような「最終的な単語」に注目しています

  • イベント処理関数はどの引数を渡されますか?常に渡される標準の引数のセットはありますか?
  • 作成するカスタムコンポーネントのカスタムイベントを定義する方法 これらのカスタムイベントを起動するにはどうすればよいですか?
  • 戻り値(true / false)は、イベントがどのようにバブルするかに影響しますか?そうでない場合、イベントハンドラの内部または外部からイベントバブリングをどのように制御できますか?
  • イベントリスナーを登録する標準的な方法はありますか?(私は今までに2つの異なる方法に出会いましたが、それぞれの方法が使用された理由がわかりません)。

たとえば、この質問では、イベントハンドラーがかなりの数の引数を受け取ることができると思います。ハンドラーへの引数が2つしかない他のチュートリアルを見てきました。何が変わりますか?


2
気づいた...トピック外?
jrharshath 14

12
質問に対する88の賛成票、最初の回答に対する155の賛成票、そして素晴らしく力強いAndrewは、これはトピックから外れていると判断しました。大変なパワートリップが続いています!
ボートコーダー2014

3
ここでの回答は金鉱であるので、私はこの質問を再開することに投票しました。QとAのスタイルに合うように質問を編集しました。
dbrin、2015年

1
この質問は本当に役に立ちます。本物の質問なので、もう一度開いてください。盲目的にそれを閉じることはできません。
Piyush Dholariya 2015年

2
これはよく書かれた質問であり、私はそれを閉じる理由はないと思います。これを話題から外すのはばかげています。再開に投票しました。
Mike Fuchs

回答:


222

まず、DOM要素のイベント処理について説明します。

DOMノードのイベント処理

まず、DOMノードを直接操作する必要はありません。代わりに、おそらくExt.Elementインターフェイスを利用したいと思うでしょう。イベントハンドラーを割り当てる目的でElement.addListenerElement.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ミックスインを利用して実現されています。イベントを適切に処理するには、ウィジェットがExt.util.Observableミックスインとして含まれている必要があります。すべての組み込みウィジェット(パネル、フォーム、ツリー、グリッドなど)はExt.util.Observable、デフォルトでミックスインとして持っています。

ウィジェットの場合、ハンドラーを割り当てる方法は2つあります。1つ目はメソッド(または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番目の方法は、ウィジェットのリスナー構成を使用することです。

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ウィジェットは特別な種類のウィジェットであることに注意してください。クリックイベントは、handlerconfig を使用してこのウィジェットに割り当てることができます。

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

3
これは貪欲ですが、いくつかの設定を介して「addEvents」を実行する方法はありますか?:)
jrharshath

@jrharshath、私が知る限り、残念ながら、configを使用してそれを行う方法はありません。
モレキュラーマン

どうやってこれらを作成するのですか-'myspecialevent1'、添付して処理したようですが、どのように作成しますか?
heyNow

1
素晴らしい答え!私はExtJに不慣れで、ページ内の任意の要素を参照し、jQueryのようにそれらでイベントハンドラーを使用する方法を探していました。あなたは私に教えました!ありがとう!
Rutwick Gangurde 2014

1
「イベントのバブリングの防止」セクションでの小さなエラー。stopPropagationはイベントのブブリングを防止するために使用され、preventDefaultはデフォルトの動作/アクションを防止するために使用されます。
MatRt 2014年

44

アプリケーション全体のイベントの発生

コントローラを互いに通信させる方法...

上記の非常に素晴らしい答えに加えて、コントローラー間の通信を可能にする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);

この方法はコントローラーに限定されません。どのコンポーネントでも、コンポーネントオブジェクトを入力パラメータースコープとして配置することで、カスタムイベントを処理できます。

Sencha Docsで見つかりました:MVCパート2


1
アプリケーション全体のカスタムイベントの発生に関しては、ExtJS V5.1の公開後に、Ext.GlobalEventsを使用する新しいメソッドがあります。あなたがイベントを発生するときは、呼び出しExt.GlobalEvents.fireEvent('custom_event');、イベントのハンドラを登録すると、あなたが呼び出すExt.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope};ここでフィドル。この方法はコントローラーに限定されません。すべてのコンポーネントは、コンポーネントオブジェクトを入力パラメーターとして配置することで、カスタムイベントを処理できますscope。質問を再開する必要があります。
gm2008、2015

15

コントローラーイベントリスナーのもう1つのトリック。

ワイルドカードを使用して、任意のコンポーネントからのイベントを監視できます。

this.control({
   '*':{ 
       myCustomEvent: this.doSomething
   }
});

12

上記の優れた回答にいくつかペンスを追加したかっただけです。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')">

参考までに、this.addEventsはEXT JS 5.0から廃止されました。そのため、ここでイベントを追加する必要はありません
Ajay Sharma

11

質問の一部ではないにしても、知っておくと役立つことが2つだけあります。

このrelayEventsメソッドを使用して、コンポーネントに別のコンポーネントの特定のイベントをリッスンし、最初のコンポーネントから発生したかのようにそれらを再度発生させることができます。APIドキュメントは、ストアloadイベントをリレーするグリッドの例を示しています。複数のサブコンポーネントをカプセル化するカスタムコンポーネントを作成する場合に非常に便利です。

逆の方法、つまりカプセル化コンポーネントが受け取ったイベントをmycmpサブコンポーネントの1つに渡すには、次のsubcmpようにします。

mycmp.on('show' function (mycmp, eOpts)
{
   mycmp.subcmp.fireEvent('show', mycmp.subcmp, eOpts);
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.