Updated guide-events en/ru

This commit is contained in:
SilverFire - Dmitry Naumenko
2015-12-27 23:04:47 +02:00
parent b68613b746
commit e0f4114d77
2 changed files with 104 additions and 25 deletions

View File

@ -225,61 +225,70 @@ Event::off(Foo::className(), Foo::EVENT_HELLO);
Обработчики событий на уровне интерфейсов <span id="interface-level-event-handlers"></span>
-------------
Еще более общим случаем, чем обработка событий на уровне класса, является обработка на уровнне *интерфейсов*. Для этого по аналогии с обработчиками событий на уровне классов, необходимо вызвать статический метод [[yii\base\Event::on()]], передав ему в качестве первого параметра имя интерфейса. В этом случае инициализация события для любого класса, реализующего указанный интерфейс, будет приводить к срабатыванию соответствующего обработчика.
Существует еще более абстрактный способ обработки событий.
Вы можете создать отдельный интерфейс для общего события и реализовать его в классах, где это необходимо.
Например, имеется следующий интерфейс:
Например, создадим следующий интерфейс:
```php
interface MyInterface
interface DanceEventInterface
{
const EVENT_HELLO = 'hello';
const EVENT_DANCE = 'dance';
}
```
И классы:
И два класса, которые его реализовывают:
```php
class MyClass1 extends Component implements MyInterface
class Dog extends Component implements DanceEventInterface
{
public function myFunction()
public function meetBuddy()
{
$this->trigger(MyInterface::EVENT_HELLO);
echo "Woof!";
$this->trigger(DanceEventInterface::EVENT_DANCE);
}
}
class MyClass2 extends Component implements MyInterface
class Developer extends Component implements DanceEventInterface
{
public function myFunction()
public function testsPassed()
{
$this->trigger(MyInterface::EVENT_HELLO);
echo "Yay!";
$this->trigger(DanceEventInterface::EVENT_DANCE);
}
}
```
В этом случае, для того, чтобы подписаться на события в любом из классов `MyClass1` или `MyClass2` достаточно добавить следующий код:
Для обработки события `EVENT_DANCE`, инициализированного любым из этих классов,
вызовите [[yii\base\Event::on()|Event:on()]], передав ему в качестве первого параметра имя интерфейса.
```php
Event::on('MyInterface', MyInterface::EVENT_HELLO, function ($event) {
echo $event->sender; // Выводит MyClass1 или MyClass2 в зависимости от класса, вызвавшего событие
})
Event::on('DanceEventInterface', DanceEventInterface::EVENT_DANCE, function ($event) {
Yii::trace($event->sender->className . ' just danced'); // Оставит запись в журнале о том, что кто-то танцевал
});
```
Обратите внимание, что в отличие от событий на *уровне класса*, для событий на *уровне интерфейса* статический вызов метода [[yii\base\Event::trigger()]] невозможен:
Вы можете также инициализировать эти события:
```php
Event::trigger('MyInterface', MyInterface::EVENT_HELLO); // Приведет к ошибке
Event::trigger(MyClass1::className(), MyInterface::EVENT_HELLO); // Корректная запись, обработчик будет вызван
Event::trigger(DanceEventInterface::className(), DanceEventInterface::EVENT_DANCE);
```
Отсоединить обработчик события на уровне класса можно с помощью метода [[yii\base\Event::off()]]. Например:
Однако, невозможно инициализировать событие во всех классах, которые реализуют интерфейс:
```php
// отсоединение $handler
Event::off('MyInterface', MyInterface::EVENT_HELLO, $handler);
// НЕ БУДЕТ РАБОТАТЬ
Event::trigger('DanceEventInterface', DanceEventInterface::EVENT_DANCE); // ошибка
```
// отсоединяются все обработчики MyInterface::EVENT_HELLO
Event::off('MyInterface', MyInterface::EVENT_HELLO);
Отсоединить обработчик события можно с помощью метода [[yii\base\Event::off()|Event::off()]]. Например:
```php
// отсоединяет $handler
Event::off('DanceEventInterface', DanceEventInterface::EVENT_DANCE, $handler);
// отсоединяются все обработчики DanceEventInterface::EVENT_DANCE
Event::off('DanceEventInterface', DanceEventInterface::EVENT_DANCE);
```
Глобальные события <span id="global-events"></span>

View File

@ -252,6 +252,76 @@ Event::off(Foo::className(), Foo::EVENT_HELLO);
```
Events using interfaces <span id="interface-level-event-handlers"></span>
-------------
There is even more abstract way to deal with events. You can create a separated interface for the special event and
implement it in classes, where you need it.
For example we can create the following interface:
```php
interface DanceEventInterface
{
const EVENT_DANCE = 'dance';
}
```
And two classes, that implement it:
```php
class Dog extends Component implements DanceEventInterface
{
public function meetBuddy()
{
echo "Woof!";
$this->trigger(DanceEventInterface::EVENT_DANCE);
}
}
class Developer extends Component implements DanceEventInterface
{
public function testsPassed()
{
echo "Yay!";
$this->trigger(DanceEventInterface::EVENT_DANCE);
}
}
```
To handle the `EVENT_DANCE`, triggered by any of these classes, call [[yii\base\Event::on()|Event::on()]] and
pass the interface name as the first argument:
```php
Event::on('DanceEventInterface', DanceEventInterface::EVENT_DANCE, function ($event) {
Yii::trace($event->sender->className . ' just danced'); // Will log that Dog or Developer danced
})
```
You can trigger the event of those classes:
```php
Event::trigger(DanceEventInterface::className(), DanceEventInterface::EVENT_DANCE);
```
But please notice, that you can not trigger all the classes, that implement the interface:
```php
// DOES NOT WORK
Event::trigger('DanceEventInterface', DanceEventInterface::EVENT_DANCE); // error
```
Do detach event handler, call [[yii\base\Event::off()|Event::off()]]. For example:
```php
// detaches $handler
Event::off('DanceEventInterface', DanceEventInterface::EVENT_DANCE, $handler);
// detaches all handlers of DanceEventInterface::EVENT_DANCE
Event::off('DanceEventInterface', DanceEventInterface::EVENT_DANCE);
```
Global Events <span id="global-events"></span>
-------------
@ -278,4 +348,4 @@ which will be triggered by the object. Instead, the handler attachment and the e
done through the Singleton (e.g. the application instance).
However, because the namespace of the global events is shared by all parties, you should name the global events
wisely, such as introducing some sort of namespace (e.g. "frontend.mail.sent", "backend.mail.sent").
wisely, such as introducing some sort of namespace (e.g. "frontend.mail.sent", "backend.mail.sent").