Symfony2 EventDispatcher組件,eventdispatcher_PHP教程

來源:互聯網
上載者:User

Symfony2 EventDispatcher組件,eventdispatcher


一個外掛程式系統中,A外掛程式在不影響其它外掛程式的前提下,添加新的方法,或者在一個方法運行前做一些準備工作,通過繼承來實現擴充是很不容易的,由於外掛程式之間的關聯關係,A外掛程式的改變也會使得關聯的外掛程式被動的修改。 Symfony2的EventDispatcher組件實現了中介者(mediator)模式,實現了外掛程式之間的解耦和關聯的關係。 舉個栗子,在HttpKernel組件中,一旦Response被建立了,在Response發送給用戶端的時候,允許系統的其它模組修改它是很有必要和很有用的(例如:在頭部添加緩衝欄位)。Symfony2核心調度kernel.response事件,那麼監聽該事件的監聽器就可以修改Response對象了: a) 監聽器(PHP對象)告訴一個特定的dispatcher類,它要監聽kernel.response事件; b) 在某一時刻,Symfony就會告訴dispatcher調度kernel.response事件,把一個包含Response對象的Event對象傳入事件調度方法EventDispatcher::dispatch() c) dispatcher通知所有監聽kernel.response事件的監聽器運行,允許這些監聽器修改Response對象。 使用方法 Events 當一個事件被調度,該事件會有一個唯一的名稱(例如:kernel.response),可以被任意多個監聽器監聽。同時執行個體化一個Event對象,並傳入到所有的監聽器中。在後面會看到,Event對象包含了被調度事件的資料。 命名規範 事件名可以是任意的字串,但是可以遵循以下幾點命名規範: * 只使用小寫字元、數字、點、底線; * 首碼名使用帶有點的命名; * 結束部分的名字使用一個能表達當前事件行為的動詞; 事件名和事件對象 dispatcher調度事件通知監聽器時候,會把一個Event對象作為參數傳入到監聽器中。基類的Event非常簡單,只有一個停止事件傳遞給下一個監聽器的方法,沒有太多別的了。 通常,一個特定事件的資料都會儲存到Event對象中,方便把資料傳遞給監聽器。在kernel.response事件中,傳入到監聽器的Event對象是子類FliterResponseEvent的對象,FliterResponseEvent是Event的子類。FliterResponseEvent包含getReponse和setResponse方法,允許監聽器獲得或者修改Response對象。 總的來說:建立一個監聽特定事件的監聽器的時候,Event的一個子類會傳入到監聽器中,監聽器可以通過該子類的方法獲得和修改資訊。 事件調度器(dispatcher) dispatcher是事件調度系統的核心,一般來說,一個dispatcher內包含一個監聽器的列表,當一個事件需要被調度的時候,dispatcher就會通知它包含的所有監聽該事件的監聽器。
1 use Symfony\Component\EventDispatcher\EventDispatcher;2 3 $dispatcher = new EventDispatcher();
關聯監聽器 把監聽器添加到dispatcher上,監聽特定的事件,那麼該事件被調度的時候,dispatcher就會通知監聽器工作了。dispatcher使用addListener方法把一個監聽器(PHP callable)添加到一個事件上。
1 $listener = new AcmeListener();2 $dispatcher->addListener('foo.action', array($listener, 'onFooAction'));
addListener方法有三個參數: * 監聽器需要監聽是的事件的名稱; * 監聽器(一個PHP callable); * 一個可選的表示優先順序的整數(數值越高優先順序越高,監聽器就會更早的被觸發),預設為0,如果優先順序一樣,那麼誰先添加就先觸發;
PHP callable是指能作為參數傳入call_user_func()或者傳入is_callable()函數執行後返回true的PHP 變數。PHP callable可以是 \Closure執行個體,一個實現了__invoke方法的對象,或者是表示一個函數的字串,或者一個表示對象方法或者類方法的數組。 到目前為止,我們看過把一個PHP對象作為監聽器,我們也可以把Closure對象作為監聽器。
1 use Symfony\Component\EventDispatcher\Event;2 3 $dispatcher->addListener('foo.action', function (Event $event) {4     // will be executed when the foo.action event is dispatched5 });
    在上面的例子中,foo.action事件被調度,dispatcher就調用AcmeListener::onFooAction方法,並把Event對象作為唯一的參數傳入方法中。
 1 use Symfony\Component\EventDispatcher\Event; 2  3 class AcmeListener 4 { 5     // ... 6  7     public function onFooAction(Event $event) 8     { 9         // ... do something10     }11 }

     在實際使用中,都是傳入一個特定的Event子類的對象到監聽器,例如FilterResponseEvent:

1 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;2 3 public function onKernelResponse(FilterResponseEvent $event)4 {5     $response = $event->getResponse();6     $request = $event->getRequest();7 8     // ...9 }
建立和調度事件 除了系統內建的事件,我們也可以建立和調度自訂的事件。這是很有好處的,當我們使用第三方類庫的時,還有可以使不同的組件之間解耦,使系統更靈活健壯。 靜態Events類 假如我們要建立一個事件——store.order——當訂單被建立的時候就會被觸發。
namespace Acme\StoreBundle;final class StoreEvents{    /**     * 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     */    const STORE_ORDER = 'store.order';}
這個類並沒有什麼方法,也不做什麼操作,只是定義了事件名稱,方便管理和組織事件。監聽這個事件的監聽器都會被傳入一個FilterOrderEvent對象。 建立一個Event對象 接著,當你調度這個新的事件的時候,會建立一個Event對象傳如到dispatcher的dispatch()方法,dispatcher就把這個Event對象傳給所有的監聽該事件的監聽器。如果我們不需要向監聽器傳入任何資訊,那麼可以使用系統預設的Symfony\Component\EventDispatcher\Event 類。然而,很多時候,我們都需要傳入特定的資訊到監聽器,那麼我們可以建立一個類繼承Symfony\Component\EventDispatcher\Event。 例如,我們需要在所有的監聽器中傳入order對象:
 1 namespace Acme\StoreBundle\Event; 2  3 use Symfony\Component\EventDispatcher\Event; 4 use Acme\StoreBundle\Order; 5  6 class FilterOrderEvent extends Event 7 { 8     protected $order; 9 10     public function __construct(Order $order)11     {12         $this->order = $order;13     }14 15     public function getOrder()16     {17         return $this->order;18     }19 }
所有監聽器都可以通過FilterOrderEvent的getOrder方法獲得order對象。 調度事件 dispatcher的dispatch()方法通知監聽給定的事件的所有監聽器,有兩個參數,一個是需要調度的事件名,另一個就是傳給所有監聽器的Event對象。
 1 use Acme\StoreBundle\StoreEvents; 2 use Acme\StoreBundle\Order; 3 use Acme\StoreBundle\Event\FilterOrderEvent; 4  5 // the order is somehow created or retrieved 6 $order = new Order(); 7 // ... 8  9 // create the FilterOrderEvent and dispatch it10 $event = new FilterOrderEvent($order);11 $dispatcher->dispatch(StoreEvents::STORE_ORDER, $event);

    FilterOrderEvent對象作為參數傳入到dispatch方法,現在,任何監聽store.order事件的監聽器都會接收到FilterOrderEvent對象,並通過調用getOrder方法獲得order對象。

1 // some listener class that's been registered for "store.order" event2 use Acme\StoreBundle\Event\FilterOrderEvent;3 4 public function onStoreOrder(FilterOrderEvent $event)5 {6     $order = $event->getOrder();7     // do something to or with the order8 }
Event Subscribers 最普遍的監聽事件的方法是註冊一個監聽器到dispatcher中,一個監聽器可以監聽一個或者多個事件。 還有另一種監聽事件的方法是使用Event SubScriber,Event SubScriber是一個PHP類,能夠準確的告訴dispatcher它訂閱了那些事件。實現EventSubscriberInterface介面,該介面有一個靜態方法getSubscriberdEvents。
namespace Acme\StoreBundle\Event;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\HttpKernel\Event\FilterResponseEvent;class StoreSubscriber implements EventSubscriberInterface{    public static function getSubscribedEvents()    {        return array(            'kernel.response' => array(                array('onKernelResponsePre', 10),                array('onKernelResponseMid', 5),                array('onKernelResponsePost', 0),            ),            'store.order'     => array('onStoreOrder', 0),        );    }    public function onKernelResponsePre(FilterResponseEvent $event)    {        // ...    }    public function onKernelResponseMid(FilterResponseEvent $event)    {        // ...    }    public function onKernelResponsePost(FilterResponseEvent $event)    {        // ...    }    public function onStoreOrder(FilterOrderEvent $event)    {        // ...    }}

這個監聽器類很簡單,告訴了dispatcher監聽了什麼事件,還有監聽的事件觸發的方法。addSubscriber()方法把subscriber註冊到dispatcher。

1 use Acme\StoreBundle\Event\StoreSubscriber;2 3 $subscriber = new StoreSubscriber();4 $dispatcher->addSubscriber($subscriber);
dispatcher準確的把Subscriber註冊到EventSubscriberInterface::getSubscriberdEvents()返回的事件裡,EventSubscriberInterface::getSubscriberdEvents()方法返回一個數組,數組的鍵對應Subscriber監聽的事件,值對應這Subscriber處理該事件調用的一個方法或者一組方法。上面的例子中,一組監聽器的方法對應這一個事件,同時我們也可以設定優先權來控制這組方法的執行先後順序。當kernel.response事件被觸發 onKernelResponsePre , onKernelResponseMid , 和 onKernelResponsePost三個方法就會先後執行。 停止事件的傳遞 在一些情況下,監聽器可以停止事件傳遞下去,防止後續的監聽器被調用,換句話說,監聽器必須通知dispatcher停止傳遞事件給後續的監聽器。在監聽器裡面實現stopPropagation()方法:
1 use Acme\StoreBundle\Event\FilterOrderEvent;2 3 public function onStoreOrder(FilterOrderEvent $event)4 {5     // ...6 7     $event->stopPropagation();8 }
那麼,監聽了store.order事件的還沒有執行的監聽器就不會在被執行。 通過isPropagationStopped()方法可以判斷一個事件是否被停止。
1 $dispatcher->dispatch('foo.event', $event);2 if ($event->isPropagationStopped()) {3     // ...4 }


AS3 的 EventDispatcher類

EventDispatcher這個就是as3裡面事件寄件者,這個也是相對as2增加一個很好的功能,只有繼承自這個類的對象才可以發送事件,dispatchEvent()就是發送事件的方法。比如你建立了一個對象A,你想讓這個對象發生了某些變化後,通知別的對象,就可以用 dispatchEvent(new Event("yourEvent"))然後你在別的地方調用到A地方就可以對A加一個接聽程式
A.addEventListener("yourEvent",yourfunction) 這個事件可以自訂,一般的對象都是EventDispatcher的子類的;
下面的網址有官方比較詳細的說明可以去參考一下;help.adobe.com/...r.html
 

flex自訂群組件怎向另一個自訂群組件傳值

有兩種方法1.通過id直接調用另一個組件中接收值的對象,對其賦值!ex://b的值就傳給a了 與官方組件差不多 如果是要給自定組件內部對象傳值,也是直接通過id調用子物件id a.text = b.text</mx:Script>2.通過自訂事件 這種方法比較靈活//在要使用值的地方添加監聽 callback為回呼函數當該事件被激發,就會調用這個方法 傳過來的值在這個//裡面可以接收到 LoadDataEvent.dispatcher.addEventListener(“testEvent”,callback);//callback寫法function callback(event:LoadDataEvent){ //event.data就是你想要的資料 這個也不一定要看你的loadDataEvent怎麼定義了}//在傳送值的地方派發事件,在事件中可以攜帶你想要傳遞的值 dataLoadDataEvent.dispatcher.addEventListener(new LoadDataEvent("testEvent",data));//LoadDataEvent的定義import flash.events.Event;
import flash.events.EventDispatcher;
/**
* 自定事件類別,用於為組件載入資料
* @author 袁金龍
* @date 2010-07-08
*/
public class LoadDataEvent extends Event
{
public static const dispatcher: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;
}
override public function clone():Event{
return new LoadDataEvent(type, bubbles, cancelable, data);
}
 

http://www.bkjia.com/PHPjc/890819.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/890819.htmlTechArticleSymfony2 EventDispatcher組件,eventdispatcher 一個外掛程式系統中,A外掛程式在不影響其它外掛程式的前提下,添加新的方法,或者在一個方法運行前做一些准...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.