ホームページ > バックエンド開発 > PHPチュートリアル > Symfony2 EventDispatcher コンポーネント、eventdispatcher_PHP チュートリアル

Symfony2 EventDispatcher コンポーネント、eventdispatcher_PHP チュートリアル

WBOY
リリース: 2016-07-13 10:17:35
オリジナル
1286 人が閲覧しました

Symfony2 EventDispatcher コンポーネント、eventdispatcher

プラグイン システムでは、プラグイン A は他のプラグインに影響を与えることなく新しいメソッドを追加したり、メソッドを実行する前に準備作業を行ったりすることができます。継承による拡張を実現するのは簡単ではありません。はい、プラグイン間の関係により、プラグイン A を変更すると、関連するプラグインも受動的に変更されます。 Symfony2 の EventDispatcher コンポーネントはメディエーター モードを実装し、プラグイン間の分離と関連付けを実現します。 ​ たとえば、HttpKernel コンポーネントでは、レスポンスが作成されると、レスポンスがクライアントに送信されるときにシステムの他のモジュールがレスポンスを変更できるようにすることが必要であり、これは便利です (例: ヘッダーにキャッシュ フィールドを追加する)。 Symfony2 カーネルは kernel.response イベントを送出し、イベントをリッスンするリスナーは Response オブジェクトを変更できます。 a) リスナー (PHP オブジェクト) は、特定のディスパッチャー クラスに kernel.response イベントをリッスンしたいことを伝えます。 ​ b) ある時点で、Symfony はディスパッチャに kernel.response イベントをスケジュールし、Response オブジェクトを含む Event オブジェクトをイベントディスパッチメソッド EventDispatcher::dispatch() に渡すように指示します。 ​ c) ディスパッチャーは、kernel.response イベントをリッスンするすべてのリスナーに実行するよう通知し、これらのリスナーが Response オブジェクトを変更できるようにします。 ​ 使用方法イベント ​ イベントがスケジュールされると、イベントには一意の名前 (例: kernel.response) が付けられ、任意の数のリスナーがリッスンできます。同時に Event オブジェクトをインスタンス化し、すべてのリスナーに渡します。後で説明するように、Event オブジェクトには、スケジュールされたイベントに関するデータが含まれています。 ​ 命名規則 イベント名には任意の文字列を使用できますが、次の命名規則に従うことができます。 ​ * 小文字、数字、ドット、アンダースコアのみを使用してください。 ​ * ドットを含むプレフィックス名を使用します。 ​ * 終了部分の名前には、現在のイベントの動作を表現できる動詞が使用されています。 ​ イベント名とイベントオブジェクト ​ ディスパッチャーは、リスナーに通知するためにイベントをディスパッチするときに、Event オブジェクトをパラメーターとしてリスナーに渡します。基本クラス Event は非常に単純で、イベントが次のリスナーに渡されるのを停止するメソッドが 1 つだけあり、他にはあまりありません。 通常、特定のイベントのデータは、リスナーへのデータの受け渡しを容易にするために Event オブジェクトに保存されます。 kernel.response イベントでは、リスナーに渡される Event オブジェクトは、Event のサブクラスであるサブクラス FliterResponseEvent のオブジェクトです。 FliterResponseEvent には getReponse メソッドと setResponse メソッドが含まれており、リスナーが Response オブジェクトを取得または変更できるようになります。 一般に: 特定のイベントをリッスンするリスナーを作成する場合、Event のサブクラスがリスナーに渡され、リスナーはサブクラスのメソッドを通じて情報を取得および変更できます。 ​ イベントディスパッチャー(ディスパッチャー) ​ ディスパッチャーはイベント スケジューリング システムの中核です。一般に、ディスパッチャーにはリスナーのリストが含まれており、イベントをディスパッチする必要がある場合、そのイベントをリッスンしているすべてのリスナーに通知します。 リーリー ​ 関連リスナー ​ 特定のイベントをリッスンするリスナーをディスパッチャーに追加すると、イベントがスケジュールされると、ディスパッチャーはリスナーに動作するように通知します。ディスパッチャーは、addListener メソッドを使用して、リスナー (PHP 呼び出し可能) をイベントに追加します。 リーリー ​ addListener メソッドには 3 つのパラメータがあります。 * リスナーがリッスンする必要があるイベントの名前。 * リスナー (PHP 呼び出し可能); * 優先度を表すオプションの整数 (値が大きいほど、優先度が高く、リスナーがより早くトリガーされます)。デフォルトは 0 です。優先度が同じ場合、最初に追加した人が最初にトリガーされます。 ​ リーリー 上記の例では、foo.action イベントがディスパッチされ、ディスパッチャは AcmeListener::onFooAction メソッドを呼び出し、Event オブジェクトを唯一のパラメータとしてメソッドに渡します。 リーリー

実際の使用では、FilterResponseEvent:

など、特定のEventサブクラスのオブジェクトがリスナーに渡されます。  
<span>1</span> <span>use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
</span><span>2</span> 
<span>3</span> <span>public</span> function onKernelResponse(FilterResponseEvent $<span>event</span><span>)
</span><span>4</span> <span>{
</span><span>5</span>     $response = $<span>event</span>-><span>getResponse();
</span><span>6</span>     $request = $<span>event</span>-><span>getRequest();
</span><span>7</span> 
<span>8</span>     <span>//</span><span> ...</span>
<span>9</span> }
ログイン後にコピー
创建和调度事件 除了系统内置的事件,我们也可以创建和调度自定义的事件。这是很有好处的,当我们使用第三方类库的时,还有可以使不同的组件之间解耦,使系统更灵活健壮。 静态的Events类 假如我们要创建一个事件——store.order——当订单被创建的时候就会被触发。
<span>namespace</span><span> Acme\StoreBundle;

final </span><span>class</span><span> StoreEvents
{
    </span><span>/*</span><span>*
     * The store.order event is thrown each time an order is created
     * in the system.
     *
     * The event listener receives an
     * Acme\StoreBundle\Event\FilterOrderEvent instance.
     *
     * @var string
     </span><span>*/</span>
    <span>const</span> STORE_ORDER = <span>'</span><span>store.order</span><span>'</span><span>;
}</span>
ログイン後にコピー
这个类并没有什么方法,也不做什么操作,只是定义了事件名称,方便管理和组织事件。监听这个事件的监听器都会被传入一个FilterOrderEvent对象。 创建一个Event对象 接着,当你调度这个新的事件的时候,会创建一个Event对象传如到dispatcher的dispatch()方法,dispatcher就把这个Event对象传给所有的监听该事件的监听器。如果我们不需要向监听器传入任何信息,那么可以使用系统默认的Symfony\Component\EventDispatcher\Event 类。然而,很多时候,我们都需要传入特定的信息到监听器,那么我们可以创建一个类继承Symfony\Component\EventDispatcher\Event。 例如,我们需要在所有的监听器中传入order对象:
<span> 1</span> <span>namespace</span><span> Acme\StoreBundle\Event;
</span><span> 2</span> 
<span> 3</span> <span>use Symfony\Component\EventDispatcher\Event;
</span><span> 4</span> <span>use Acme\StoreBundle\Order;
</span><span> 5</span> 
<span> 6</span> <span>class</span><span> FilterOrderEvent extends Event
</span><span> 7</span> <span>{
</span><span> 8</span>     <span>protected</span><span> $order;
</span><span> 9</span> 
<span>10</span>     <span>public</span><span> function __construct(Order $order)
</span><span>11</span> <span>    {
</span><span>12</span>         $<span>this</span>->order =<span> $order;
</span><span>13</span> <span>    }
</span><span>14</span> 
<span>15</span>     <span>public</span><span> function getOrder()
</span><span>16</span> <span>    {
</span><span>17</span>         <span>return</span> $<span>this</span>-><span>order;
</span><span>18</span> <span>    }
</span><span>19</span> }
ログイン後にコピー
所有监听器都可以通过FilterOrderEvent的getOrder方法获得order对象。 调度事件 dispatcher的dispatch()方法通知监听给定的事件的所有监听器,有两个参数,一个是需要调度的事件名,另一个就是传给所有监听器的Event对象。
<span> 1</span> <span>use Acme\StoreBundle\StoreEvents;
</span><span> 2</span> <span>use Acme\StoreBundle\Order;
</span><span> 3</span> <span>use Acme\StoreBundle\Event\FilterOrderEvent;
</span><span> 4</span> 
<span> 5</span> <span>//</span><span> the order is somehow created or retrieved</span>
<span> 6</span> $order = <span>new</span><span> Order();
</span><span> 7</span> <span>//</span><span> ...
</span><span> 8</span> 
<span> 9</span> <span>//</span><span> create the FilterOrderEvent and dispatch it</span>
<span>10</span> $<span>event</span> = <span>new</span><span> FilterOrderEvent($order);
</span><span>11</span> $dispatcher->dispatch(StoreEvents::STORE_ORDER, $<span>event</span>);
ログイン後にコピー

    FilterOrderEvent对象作为参数传入到dispatch方法,现在,任何监听store.order事件的监听器都会接收到FilterOrderEvent对象,并通过调用getOrder方法获得order对象。

<span>1</span> <span>//</span><span> some listener class that's been registered for "store.order" event</span>
<span>2</span> <span>use Acme\StoreBundle\Event\FilterOrderEvent;
</span><span>3</span> 
<span>4</span> <span>public</span> function onStoreOrder(FilterOrderEvent $<span>event</span><span>)
</span><span>5</span> <span>{
</span><span>6</span>     $order = $<span>event</span>-><span>getOrder();
</span><span>7</span>     <span>//</span><span> do something to or with the order</span>
<span>8</span> }
ログイン後にコピー
Event Subscribers 最普遍的监听事件的方法是注册一个监听器到dispatcher中,一个监听器可以监听一个或者多个事件。 还有另一种监听事件的方法是使用Event SubScriber,Event SubScriber是一个PHP类,能够准确的告诉dispatcher它订阅了那些事件。实现EventSubscriberInterface接口,该接口有一个静态的方法getSubscriberdEvents。
<span>namespace</span><span> Acme\StoreBundle\Event;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;

</span><span>class</span><span> StoreSubscriber implements EventSubscriberInterface
{
    </span><span>public</span> <span>static</span><span> function getSubscribedEvents()
    {
        </span><span>return</span><span> array(
            </span><span>'</span><span>kernel.response</span><span>'</span> =><span> array(
                array(</span><span>'</span><span>onKernelResponsePre</span><span>'</span>, <span>10</span><span>),
                array(</span><span>'</span><span>onKernelResponseMid</span><span>'</span>, <span>5</span><span>),
                array(</span><span>'</span><span>onKernelResponsePost</span><span>'</span>, <span>0</span><span>),
            ),
            </span><span>'</span><span>store.order</span><span>'</span>     => array(<span>'</span><span>onStoreOrder</span><span>'</span>, <span>0</span><span>),
        );
    }

    </span><span>public</span> function onKernelResponsePre(FilterResponseEvent $<span>event</span><span>)
    {
        </span><span>//</span><span> ...</span>
<span>    }

    </span><span>public</span> function onKernelResponseMid(FilterResponseEvent $<span>event</span><span>)
    {
        </span><span>//</span><span> ...</span>
<span>    }

    </span><span>public</span> function onKernelResponsePost(FilterResponseEvent $<span>event</span><span>)
    {
        </span><span>//</span><span> ...</span>
<span>    }

    </span><span>public</span> function onStoreOrder(FilterOrderEvent $<span>event</span><span>)
    {
        </span><span>//</span><span> ...</span>
<span>    }
}</span>
ログイン後にコピー

这个监听器类很简单,告诉了dispatcher监听了什么事件,还有监听的事件触发的方法。addSubscriber()方法把subscriber注册到dispatcher。

<span>1</span> <span>use Acme\StoreBundle\Event\StoreSubscriber;
</span><span>2</span> 
<span>3</span> $subscriber = <span>new</span><span> StoreSubscriber();
</span><span>4</span> $dispatcher->addSubscriber($subscriber);
ログイン後にコピー
dispatcher准确的把Subscriber注册到EventSubscriberInterface::getSubscriberdEvents()返回的事件里,EventSubscriberInterface::getSubscriberdEvents()方法返回一个数组,数组的键对应Subscriber监听的事件,值对应这Subscriber处理该事件调用的一个方法或者一组方法。上面的例子中,一组监听器的方法对应这一个事件,同时我们也可以设置优先级来控制这组方法的执行先后顺序。当kernel.response事件被触<code>onKernelResponsePre, <code>onKernelResponseMid, 和 <code><span>onKernelResponsePost三个方法就会先后执行。</span> 停止事件的传递 在一些情况下,监听器可以停止事件传递下去,防止后续的监听器被调用,换句话说,监听器必须通知dispatcher停止传递事件给后续的监听器。在监听器里面实现stopPropagation()方法:
<span>1</span> <span>use Acme\StoreBundle\Event\FilterOrderEvent;
</span><span>2</span> 
<span>3</span> <span>public</span> function onStoreOrder(FilterOrderEvent $<span>event</span><span>)
</span><span>4</span> <span>{
</span><span>5</span>     <span>//</span><span> ...</span>
<span>6</span> 
<span>7</span>     $<span>event</span>-><span>stopPropagation();
</span><span>8</span> }
ログイン後にコピー
那么,监听了store.order事件的还没有执行的监听器就不会在被执行。 通过isPropagationStopped()方法可以判断一个事件是否被停止。
<span>1</span> $dispatcher->dispatch(<span>'</span><span>foo.event</span><span>'</span>, $<span>event</span><span>);
</span><span>2</span> <span>if</span> ($<span>event</span>-><span>isPropagationStopped()) {
</span><span>3</span>     <span>//</span><span> ...</span>
<span>4</span> }
ログイン後にコピー

 

AS3 的 EventDispatcher类

As3 の EventDispatcher は、このクラスから継承されたオブジェクトのみがイベントを送信できる優れた機能です。たとえば、新しいオブジェクト A を作成し、このオブジェクトで特定の変更が発生した後に他のオブジェクトに通知したい場合は、dispatchEvent(new Event("yourEvent")) を使用して、他の場所で A を呼び出すことができます。 A のリスナー
A.addEventListener("yourEvent",yourfunction) このイベントはカスタマイズでき、一般的なオブジェクトは EventDispatcher のサブクラスです。
次の Web サイトには、公式の詳細な手順が記載されています。 r.html

フレックスカスタムコンポーネントから別のカスタムコンポーネントに値を渡す方法

方法は 2 つあります: 1. 別のコンポーネントで値を受け取るオブジェクトを ID 経由で直接呼び出し、それに値を割り当てます。例://b の値a に渡すのは公式コンポーネントとほぼ同じです。カスタム コンポーネントの内部オブジェクトに値を渡したい場合は、id a.text = b.text< を通じてサブオブジェクト ID を直接呼び出すこともできます。 ;/mx:Script>2. カスタム イベントのメソッドを使用する より柔軟 //値が使用されるコールバック関数としてリスニング コールバックを追加します。イベントが発生すると、このメソッドが呼び出されます。 // LoadDataEvent.dispatcher.addEventListener("testEvent", callback );// コールバック関数の書き方 callback(event:LoadDataEvent){ //event.data は必要なデータであるとは限りません。 loadDataEvent の定義方法について}// 値が送信されるイベントをディスパッチします。イベントでは、渡したい値を運ぶことができます。 dataLoadDataEvent.dispatcher.addEventListener(new LoadDataEvent("testEvent",data));// の定義LoadDataEvent import flash.events.Event;
import flash.events.EventDispatcher;
/**
* コンポーネントのデータをロードするためのカスタム イベント クラス
* @author Yuan Jinlong
* @date 2010-07-08
*/
public class LoadDataEvent extends Event
{
public static constdispatcher:EventDispatcher=new EventDispatcher( );
public var data:Object = null;
public function LoadDataEvent(type:String, data:Object=null, bubbles:Boolean=false, cancelable :Boolean=false)
{
super(type, bubbles, cancelable);
this.EVENT_NAME = type;
this.data = data;
this.typeData = typeData;
this.tempData = tempData;
}
public をオーバーライドしますfunction clone():Event{
return new LoadDataEvent(type, bubbles, cancelable , data);
}

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/890819.html技術記事 Symfony2 EventDispatcher コンポーネント、eventdispatcher プラグイン システムでは、プラグイン A は他のプラグインに影響を与えることなく新しいメソッドを追加したり、メソッドを実行する前にいくつかの準備をしたりできます...
関連ラベル:
as3
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート