Commit ece8f641 by Alexander Makarov

Edited Russian translation of Behaviors

parent 9bf4bcbf
Поведения Поведения
========= =========
Поведения (behaviors) - это экземпляры класса [[yii\base\Behavior]] или класса, унаследованного от него. Поведения, Поведения (behaviors) — это экземпляры класса [[yii\base\Behavior]] или класса, унаследованного от него. Поведения,
также известные как [примеси](http://ru.wikipedia.org/wiki/Примесь_(программирование)), позволяют расширять также известные как [примеси](http://ru.wikipedia.org/wiki/Примесь_(программирование)), позволяют расширять
функциональность существующих [[yii\base\Component|компонентов]] без необходимости их изменения. функциональность существующих [[yii\base\Component|компонентов]] без необходимости изменения дерева наследования.
После прикрепления поведения к компоненту, его методы и свойства "внедряются" в компонент, и становятся доступными После прикрепления поведения к компоненту, его методы и свойства "внедряются" в компонент, и становятся доступными
так же, как если бы они были объявлены в самом классе компонента. Кроме того, поведение может реагировать на так же, как если бы они были объявлены в самом классе компонента. Кроме того, поведение может реагировать на
[события](concept-events.md), создаваемые компонентом, что позволяет тонко настраивать или модифицировать [события](concept-events.md), создаваемые компонентом, что позволяет тонко настраивать или модифицировать
обычное выполнение кода компонента. обычное выполнение кода компонента.
Использование Поведений <a name="using-behaviors"></a> Создание поведений <a name="defining-behaviors"></a>
--------------- ----------------------------------------------
Для использования поведения, его необходимо прикрепить к [[yii\base\Component|компоненту]]. Подробнее о том, как Поведения создаются путем расширения базового класса [[yii\base\Behavior]] или его наследников. Например,
это сделать, описано в следующем разделе.
После того, как поведение прикреплено к компоненту, его использование не вызывает сложностей. ```php
namespace app\components;
Вы можете обращаться к *публичным* переменным или [свойствам](concept-properties.md), объявленным с использованием use yii\base\Behavior;
геттеров и сеттеров в поведении, через компонент, к которому оно прикреплено, как показано ниже,
```php class MyBehavior extends Behavior
// публичное свойство "prop1" объявленное в классе поведения {
echo $component->prop1; public $prop1;
$component->prop1 = $value;
```
Аналогично, вы можете вызывать *публичные* методы поведения, private $_prop2;
```php public function getProp2()
// публичный метод bar() объявленный в классе поведения {
$component->bar(); return $this->_prop2;
}
public function setProp2($value)
{
$this->_prop2 = $value;
}
public function foo()
{
// ...
}
}
``` ```
Обратите внимание, хотя `$component` не имеет свойства `prop1` и метода `bar()`, они могут быть использованы, В приведенном выше примере, объявлен класс поведения `app\components\MyBehavior` содержащий 2 свойства
как будто являются членами этого класса. `prop1` и `prop2`, и один метод `foo()`. Обратите внимание, свойство `prop2` объявлено с использованием геттера
`getProp2()` и сеттера `setProp2()`. Это возможно, так как [[yii\base\Behavior]] является дочерним классом для
[[yii\base\Object]], который предоставляет возможность определения [свойств](concept-properties.md) через геттеры и сеттеры.
В случае, когда два поведения, имеющие свойства или методы с одинаковыми именами, прикреплены к одному компоненту, Так как этот класс является поведением, когда он прикреплён к компоненту, компоненту будут также доступны свойства `prop1`
преимущество будет у поведения, прикрепленного раньше. и `prop2`, а также метод `foo()`.
> Подсказка: Внутри поведения возможно обращаться к компоненту, к которому оно прикреплено, используя свойство
[[yii\base\Behavior::owner]].
Обработка событий компонента
-------------------------
Поведение может быть связано (associated) по имени по время прикрепления к компоненту. Это предоставляет возможность, Если поведению требуется реагировать на события компонента, к которому оно прикреплено, то необходимо переопределить
обращаться к поведению по его имени, как показано ниже, метод [[yii\base\Behavior::events()]]. Например,
```php ```php
$behavior = $component->getBehavior('myBehavior'); namespace app\components;
use yii\db\ActiveRecord;
use yii\base\Behavior;
class MyBehavior extends Behavior
{
// ...
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
];
}
public function beforeValidate($event)
{
// ...
}
}
``` ```
Также можно получить все поведения, прикрепленные к компоненту: Метод [[yii\base\Behavior::events()|events()]] должен возвращать список событий и соответствующих им обработчиков.
В приведенном выше примере, объявлено событие [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]]
и его обработчик `beforeValidate()`. Указать обработчик события, можно одним из следующих способов:
* строка с именем метода текущего поведения, как в примере выше;
* массив, содержащий объект или имя класса, и имя метода, например, `[$object, 'methodName']`;
* анонимная функция.
Функция обработчика события должна выглядеть как показано ниже, где `$event` содержит параметр
события. Более детальная информация приведена в разделе [События](concept-events.md).
```php ```php
$behaviors = $component->getBehaviors(); function ($event) {
}
``` ```
Прикрепление поведений <a name="attaching-behaviors"></a>
---------------------------------------------------
Прикрепление Поведений <a name="attaching-behaviors"></a> Прикрепить поведение к [[yii\base\Component|компоненту]] можно как статически, так и динамически. На практике
------------------- чаще используется статическое прикрепление.
Прикрепить поведение к [[yii\base\Component|компоненту]] можно статически (statically) или динамически (dynamically).
На практике, чаще используется статическое прикрепление.
Для того чтобы прикрепить поведение статически, необходимо переопределить метод Для того чтобы прикрепить поведение статически, необходимо переопределить метод [[yii\base\Component::behaviors()|behaviors()]]
[[yii\base\Component::behaviors()|behaviors()]] класса компонента. Например, компонента, к которому его планируется прикрепить. Метод [[yii\base\Component::behaviors()|behaviors()]] должен возвращать
список [конфигураций](concept-configurations.md) поведений. Конфигурация поведения представляет собой имя класса поведения,
либо массив его настроек:
```php ```php
namespace app\models; namespace app\models;
...@@ -99,17 +147,13 @@ class User extends ActiveRecord ...@@ -99,17 +147,13 @@ class User extends ActiveRecord
} }
``` ```
Метод [[yii\base\Component::behaviors()|behaviors()]] должен возвращать список
[конфигураций](concept-configurations.md) поведений. Конфигурация поведения представляет собой имя класса поведения,
либо массив его настроек.
Вы можете связать имя с поведением, указав его в качестве ключа элемента массива, соответствующего конфигурации Вы можете связать имя с поведением, указав его в качестве ключа элемента массива, соответствующего конфигурации
поведения. В таком случае, поведение называется *именованным поведением (named behavior)*. В примере выше, поведения. В таком случае, поведение называется *именованным*. В примере выше,
два именованных поведения: `myBehavior2` и `myBehavior4`. Если с поведением не связано имя, такое поведение называется два именованных поведения: `myBehavior2` и `myBehavior4`. Если с поведением не связано имя, такое поведение называется
*анонимным поведением (anonymous behavior)*. *анонимным*.
Для того, чтобы прикрепить поведение динамически, необходимо вызвать метод [[yii\base\Component::attachBehavior()]] Для того, чтобы прикрепить поведение динамически, необходимо вызвать метод [[yii\base\Component::attachBehavior()]]
требуемого компонента. Например, требуемого компонента:
```php ```php
use app\components\MyBehavior; use app\components\MyBehavior;
...@@ -138,8 +182,7 @@ $component->attachBehaviors([ ...@@ -138,8 +182,7 @@ $component->attachBehaviors([
]); ]);
``` ```
Так же, прикрепить поведение к компоненту можно через [конфигурацию](concept-configurations.md), как показано ниже. Так же, прикрепить поведение к компоненту можно через [конфигурацию](concept-configurations.md), как показано ниже:
Более детальная информация приведена в разделе [Конфигурации](concept-configurations.md#configuration-format).
```php ```php
[ [
...@@ -153,117 +196,72 @@ $component->attachBehaviors([ ...@@ -153,117 +196,72 @@ $component->attachBehaviors([
] ]
``` ```
Более детальная информация приведена в разделе [Конфигурации](concept-configurations.md#configuration-format).
Отвязывание Поведений<a name="detaching-behaviors"></a> Использование поведений <a name="using-behaviors"></a>
------------------- ------------------------------------------------
Чтобы отвязать (detach) поведение, необходимо вызвать метод [[yii\base\Component::detachBehavior()]], указав имя, Для использования поведения, его необходимо прикрепить к [[yii\base\Component|компоненту]] как описано выше. После того,
связанное с поведением: как поведение прикреплено к компоненту, его использование не вызывает сложностей.
Вы можете обращаться к *публичным* переменным или [свойствам](concept-properties.md), объявленным с использованием
геттеров и сеттеров в поведении, через компонент, к которому оно прикреплено:
```php ```php
$component->detachBehavior('myBehavior1'); // публичное свойство "prop1" объявленное в классе поведения
echo $component->prop1;
$component->prop1 = $value;
``` ```
Так же, возможно отвязать *все* поведения: Аналогично, вы можете вызывать *публичные* методы поведения,
```php ```php
$component->detachBehaviors(); // публичный метод bar() объявленный в классе поведения
$component->bar();
``` ```
Обратите внимание, хотя `$component` не имеет свойства `prop1` и метода `bar()`, они могут быть использованы,
как будто являются членами этого класса.
Создание Поведений <a name="defining-behaviors"></a> В случае, когда два поведения, имеющие свойства или методы с одинаковыми именами, прикреплены к одному компоненту,
------------------ преимущество будет у поведения, прикрепленного раньше.
Поведения создаются путем расширения базового класса [[yii\base\Behavior]] или его наследников. Например, Если при прикреплении поведения к компоненту указано имя, можно обращаться к поведению по этому имени, как показано ниже:
```php ```php
namespace app\components; $behavior = $component->getBehavior('myBehavior');
use yii\base\Model;
use yii\base\Behavior;
class MyBehavior extends Behavior
{
public $prop1;
private $_prop2;
public function getProp2()
{
return $this->_prop2;
}
public function setProp2($value)
{
$this->_prop2 = $value;
}
public function foo()
{
// ...
}
}
``` ```
В приведенном выше примере, объявлен класс поведения `app\components\MyBehavior` содержащий 2 свойства
`prop1` и `prop2`, и один метод `foo()`, которые будут доступны компоненту, к которому оно прикреплено.
Обратите внимание, свойство `prop2` объявлено с использованием геттера `getProp2()` и сеттера`setProp2()`.
Это возможно, так как [[yii\base\Behavior]] является дочерним классом для [[yii\base\Object]], который предоставляет
возможность определения [свойств](concept-properties.md) через геттеры и сеттеры.
Внутри поведения возможно обращаться к свойствам компонента, к которому оно прикреплено, используя свойство
[[yii\base\Behavior::owner]].
Если поведению требуется реагировать на события компонента, к которому оно прикреплено, то необходимо переопределить Также можно получить все поведения, прикрепленные к компоненту:
метод [[yii\base\Behavior::events()]]. Например,
```php ```php
namespace app\components; $behaviors = $component->getBehaviors();
```
use yii\db\ActiveRecord;
use yii\base\Behavior;
class MyBehavior extends Behavior Отвязывание поведений<a name="detaching-behaviors"></a>
{ -------------------------------------------------
// ...
public function events() Чтобы отвязать поведение от компонента, необходимо вызвать метод [[yii\base\Component::detachBehavior()]], указав имя,
{ связанное с поведением:
return [
ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
];
}
public function beforeValidate($event) ```php
{ $component->detachBehavior('myBehavior1');
// ...
}
}
``` ```
Метод [[yii\base\Behavior::events()|events()]] должен возвращать список событий и соответствующих им обработчиков. Так же, возможно отвязать *все* поведения:
В приведенном выше примере, объявлено событие [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]]
и его обработчик `beforeValidate()`. Указать обработчик события, можно одним из следующих способов:
* строка с именем метода текущего поведения, как в примере выше;
* массив, содержащий объект или имя класса, и имя метода, например, `[$object, 'methodName']`;
* анонимная функция.
Сигнатура (signature) функции обработчика события должна выглядеть как показано ниже, где `$event` содержит параметр
события. Более детальная информация приведена в разделе [События](concept-events.md).
```php ```php
function ($event) { $component->detachBehaviors();
}
``` ```
Использование поведения `TimestampBehavior` <a name="using-timestamp-behavior"></a> Использование поведения `TimestampBehavior` <a name="using-timestamp-behavior"></a>
------------------------- --------------------------------------------------------------------------
В заключении, давайте посмотрим на [[yii\behaviors\TimestampBehavior]] - поведение, которое позволяет автоматически В заключении, давайте посмотрим на [[yii\behaviors\TimestampBehavior]] поведение, которое позволяет автоматически
обновлять атрибуты с метками времени при сохранении [[yii\db\ActiveRecord|Active Record]] моделей. обновлять атрибуты с метками времени при сохранении [[yii\db\ActiveRecord|Active Record]] моделей.
Для начала, необходимо прикрепить поведение к классу [[yii\db\ActiveRecord|Active Record]], в котором это необходимо. Для начала, необходимо прикрепить поведение к классу [[yii\db\ActiveRecord|Active Record]], в котором это необходимо:
```php ```php
namespace app\models\User; namespace app\models\User;
...@@ -292,10 +290,8 @@ class User extends ActiveRecord ...@@ -292,10 +290,8 @@ class User extends ActiveRecord
Конфигурация выше описывает следующее: Конфигурация выше описывает следующее:
* когда будет добавлена новая запись (insert), поведение должно присвоить текущую метку времени (timestamp) атрибутам * при вставке новой записи поведение должно присвоить текущую метку времени атрибутам `created_at` и `updated_at`;
`created_at` и `updated_at`; * при обновлении существующей записи поведение должно присвоить текущую метку времени атрибуту `updated_at`.
* когда будет обновлена существующая запись (update), поведение должно присвоить текущую метку времени атрибуту
`updated_at`.
Теперь, если сохранить объект `User`, то в его атрибуты `created_at` и `updated_at` будут автоматически установлены Теперь, если сохранить объект `User`, то в его атрибуты `created_at` и `updated_at` будут автоматически установлены
значения метки времени на момент сохранения записи: значения метки времени на момент сохранения записи:
...@@ -304,7 +300,7 @@ class User extends ActiveRecord ...@@ -304,7 +300,7 @@ class User extends ActiveRecord
$user = new User; $user = new User;
$user->email = 'test@example.com'; $user->email = 'test@example.com';
$user->save(); $user->save();
echo $user->created_at; // отобразить метку времени на момент сохранения записи echo $user->created_at; // выведет метку времени на момент сохранения записи
``` ```
Поведение [[yii\behaviors\TimestampBehavior|TimestampBehavior]] так же содержит полезный метод Поведение [[yii\behaviors\TimestampBehavior|TimestampBehavior]] так же содержит полезный метод
...@@ -316,23 +312,23 @@ $user->touch('login_time'); ...@@ -316,23 +312,23 @@ $user->touch('login_time');
``` ```
Сравнение с Трейтами <a name="comparison-with-traits"></a> Сравнение с трейтами <a name="comparison-with-traits"></a>
---------------------- ---------------------------------------------------
Несмотря на то, что поведения схожи с [трейтами](http://ru2.php.net/manual/ru/language.oop5.traits.php) тем, что Несмотря на то, что поведения схожи с [трейтами](http://ru2.php.net/manual/ru/language.oop5.traits.php) тем, что
"внедряют" свои свойства и методы в основной класс, они имеют множество отличий. Они оба имеют свои плюсы и минусы, "внедряют" свои свойства и методы в основной класс, они имеют множество отличий. Они оба имеют свои плюсы и минусы,
и, скорее, дополняют друг друга, а не заменяют. и, скорее, дополняют друг друга, а не заменяют.
### Плюсы Поведений <a name="pros-for-behaviors"></a> ### Плюсы поведений <a name="pros-for-behaviors"></a>
Поведения, как и любые другие классы, поддерживают наследование. Трейты можно рассматривать как копипейст Поведения, как и любые другие классы, поддерживают наследование. Трейты же можно рассматривать как копипейст
на уровне языка. Они не поддерживают наследование. на уровне языка. Они наследование не поддерживают.
Поведения могут быть прикреплены и отвязаны от компонента динамически, без необходимости модифицирования класса Поведения могут быть прикреплены и отвязаны от компонента динамически, без необходимости модифицирования класса
компонента. Для использование Трейтов необходимо модифицировать класс. компонента. Для использование трейтов необходимо модифицировать класс.
Поведения, в отличии от трейтов, можно настраивать. Поведения, в отличие от трейтов, можно настраивать.
Поведения можно настраивать таким образом, чтобы они реагировали на события компонента. Поведения можно настраивать таким образом, чтобы они реагировали на события компонента.
...@@ -340,7 +336,7 @@ $user->touch('login_time'); ...@@ -340,7 +336,7 @@ $user->touch('login_time');
Конфликты имен, вызванные различными трейтами, требуют ручного переименования конфликтующих свойств или методов. Конфликты имен, вызванные различными трейтами, требуют ручного переименования конфликтующих свойств или методов.
### Плюсы Трейтов <a name="pros-for-traits"></a> ### Плюсы трейтов <a name="pros-for-traits"></a>
Трейты являются гораздо более производительными, чем поведения поведений, которые, являясь объектами, требуют Трейты являются гораздо более производительными, чем поведения поведений, которые, являясь объектами, требуют
дополнительного времени и памяти. дополнительного времени и памяти.
......
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