Commit a421f9f1 by Qiang Xue

refactored component event.

parent 31777c92
......@@ -7,20 +7,20 @@ is triggered (i.e. comment will be added), our custom code will be executed.
An event is identified by a name that should be unique within the class it is defined at. Event names are *case-sensitive*.
One or multiple PHP callbacks, called *event handlers*, could be attached to an event. You can call [[trigger()]] to
One or multiple PHP callbacks, called *event handlers*, can be attached to an event. You can call [[trigger()]] to
raise an event. When an event is raised, the event handlers will be invoked automatically in the order they were
attached.
To attach an event handler to an event, call [[on()]]:
~~~
$comment->on('add', function($event) {
$post->on('update', function($event) {
// send email notification
});
~~~
In the above, we attach an anonymous function to the "add" event of the comment.
Valid event handlers include:
In the above, an anonymous function is attached to the "update" event of the post. You may attach
the following types of event handlers:
- anonymous function: `function($event) { ... }`
- object method: `array($object, 'handleAdd')`
......@@ -35,8 +35,8 @@ function foo($event)
where `$event` is an [[Event]] object which includes parameters associated with the event.
You can also attach an event handler to an event when configuring a component with a configuration array. The syntax is
like the following:
You can also attach a handler to an event when configuring a component with a configuration array.
The syntax is like the following:
~~~
array(
......@@ -46,15 +46,13 @@ array(
where `on add` stands for attaching an event to the `add` event.
You can call [[getEventHandlers()]] to retrieve all event handlers that are attached to a specified event. Because this
method returns a [[Vector]] object, we can manipulate this object to attach/detach event handlers, or adjust their
relative orders.
Sometimes, you may want to associate extra data with an event handler when you attach it to an event
and then access it when the handler is invoked. You may do so by
~~~
$handlers = $comment->getEventHandlers('add');
$handlers->insertAt(0, $callback); // attach a handler as the first one
$handlers[] = $callback; // attach a handler as the last one
unset($handlers[0]); // detach the first handler
$post->on('update', function($event) {
// the data can be accessed via $event->data
}, $data);
~~~
......
......@@ -15,12 +15,14 @@ namespace yii\base;
* And the [[handled]] property indicates if the event is handled.
* If an event handler sets [[handled]] to be true, the rest of the
* uninvoked handlers will no longer be called to handle the event.
* Additionally, an event may specify extra parameters via the [[data]] property.
*
* Additionally, when attaching an event handler, extra data may be passed
* and be available via the [[data]] property when the event handler is invoked.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Event extends \yii\base\Object
class Event extends Object
{
/**
* @var string the event name. This property is set by [[Component::trigger()]].
......@@ -39,7 +41,8 @@ class Event extends \yii\base\Object
*/
public $handled = false;
/**
* @var mixed extra custom data associated with the event.
* @var mixed the data that is passed to [[Component::on()]] when attaching an event handler.
* Note that this varies according to which event handler is currently executing.
*/
public $data;
}
......@@ -41,12 +41,12 @@ class ComponentTest extends TestCase
$component->attachBehavior('a', $behavior);
$this->assertSame($behavior, $component->getBehavior('a'));
$component->on('test', 'fake');
$this->assertEquals(1, $component->getEventHandlers('test')->count);
$this->assertTrue($component->hasEventHandlers('test'));
$clone = clone $component;
$this->assertNotSame($component, $clone);
$this->assertNull($clone->getBehavior('a'));
$this->assertEquals(0, $clone->getEventHandlers('test')->count);
$this->assertFalse($clone->hasEventHandlers('test'));
}
public function testHasProperty()
......@@ -151,34 +151,32 @@ class ComponentTest extends TestCase
public function testOn()
{
$this->assertEquals(0, $this->component->getEventHandlers('click')->getCount());
$this->assertFalse($this->component->hasEventHandlers('click'));
$this->component->on('click', 'foo');
$this->assertEquals(1, $this->component->getEventHandlers('click')->getCount());
$this->component->on('click', 'bar');
$this->assertEquals(2, $this->component->getEventHandlers('click')->getCount());
$p = 'on click';
$this->component->$p = 'foo2';
$this->assertEquals(3, $this->component->getEventHandlers('click')->getCount());
$this->assertTrue($this->component->hasEventHandlers('click'));
$this->component->getEventHandlers('click')->add('test');
$this->assertEquals(4, $this->component->getEventHandlers('click')->getCount());
$this->assertFalse($this->component->hasEventHandlers('click2'));
$p = 'on click2';
$this->component->$p = 'foo2';
$this->assertTrue($this->component->hasEventHandlers('click2'));
}
public function testOff()
{
$this->assertFalse($this->component->hasEventHandlers('click'));
$this->component->on('click', 'foo');
$this->component->on('click', array($this->component, 'myEventHandler'));
$this->assertEquals(2, $this->component->getEventHandlers('click')->getCount());
$result = $this->component->off('click', 'foo');
$this->assertTrue($result);
$this->assertEquals(1, $this->component->getEventHandlers('click')->getCount());
$result = $this->component->off('click', 'foo');
$this->assertFalse($result);
$this->assertEquals(1, $this->component->getEventHandlers('click')->getCount());
$result = $this->component->off('click', array($this->component, 'myEventHandler'));
$this->assertTrue($result);
$this->assertEquals(0, $this->component->getEventHandlers('click')->getCount());
$this->assertTrue($this->component->hasEventHandlers('click'));
$this->component->off('click', 'foo');
$this->assertFalse($this->component->hasEventHandlers('click'));
$this->component->on('click2', 'foo');
$this->component->on('click2', 'foo2');
$this->component->on('click2', 'foo3');
$this->assertTrue($this->component->hasEventHandlers('click2'));
$this->component->off('click2', 'foo3');
$this->assertTrue($this->component->hasEventHandlers('click2'));
$this->component->off('click2');
$this->assertFalse($this->component->hasEventHandlers('click2'));
}
public function testTrigger()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment