mirror of
https://github.com/yiisoft/yii.git
synced 2026-03-04 15:24:07 +01:00
175 lines
11 KiB
Plaintext
175 lines
11 KiB
Plaintext
Компонент
|
||
=========
|
||
Yii-приложения состоят из компонентов–объектов, созданных согласно спецификациям.
|
||
Компонент (component) — это экземпляр класса [CComponent] или производного от него.
|
||
Использование компонента, как правило, включает доступ к его свойствам, а также вызов и обработку его событий.
|
||
Базовый класс [CComponent] устанавливает правила, согласно которым определяются свойства и события.
|
||
|
||
Свойство компонента
|
||
-------------------
|
||
Свойство компонента схоже с открытой переменной-членом класса (public member variable).
|
||
Мы можем читать или устанавливать его значение. Например:
|
||
|
||
~~~
|
||
[php]
|
||
$width=$component->textWidth; // получаем значение свойства textWidth
|
||
$component->enableCaching=true; // устанавливаем значение свойства enableCaching
|
||
~~~
|
||
|
||
Для того чтобы создать свойство компонента, достаточно объявить открытую переменную-член в классе компонента.
|
||
Более гибкий вариант — определить методы, считывающие (getter) и записывающие (setter) значение этой
|
||
переменной, например:
|
||
|
||
~~~
|
||
[php]
|
||
public function getTextWidth()
|
||
{
|
||
return $this->_textWidth;
|
||
}
|
||
|
||
public function setTextWidth($value)
|
||
{
|
||
$this->_textWidth=$value;
|
||
}
|
||
~~~
|
||
|
||
В приведённом коде определено свойство `textWidth` (имя не чувствительно к регистру), доступное для записи.
|
||
|
||
При обращении к свойству вызывается метод чтения `getTextWidth()`, возвращающий значение свойства.
|
||
Соответственно, при присвоении значения свойству будет вызван метод записи `setTextWidth()`.
|
||
Если метод записи не определён, то свойство будет доступно только для чтения, а
|
||
при попытке записи будет выброшено исключение. Использование методов чтения и
|
||
записи имеет дополнительное преимущество: при чтении или записи значения
|
||
свойства могут быть выполнены дополнительные действия (такие как проверка на корректность,
|
||
вызов события и др.).
|
||
|
||
>Note|Примечание: Есть небольшая разница в определении свойства через методы и через простое
|
||
объявление переменной. В первом случае имя свойства не чувствительно к регистру,
|
||
во втором — чувствительно.
|
||
|
||
|
||
События компонента
|
||
------------------
|
||
События компонента — это специальные свойства, в качестве значений которых выступают
|
||
методы (называемые обработчиками событий). Назначение метода событию приведет к тому, что метод будет вызван
|
||
автоматически при возникновении этого события. Поэтому поведение компонента может быть
|
||
изменено совершенно отлично от закладываемого при разработке.
|
||
|
||
Событие компонента объявляется путём создания метода с именем, начинающимся на `on`.
|
||
Так же как и имена свойств, заданных через методы чтения и записи, имена событий
|
||
не чувствительны к регистру. Следующий код объявляет событие `onClicked`:
|
||
|
||
~~~
|
||
[php]
|
||
public function onClicked($event)
|
||
{
|
||
$this->raiseEvent('onClicked', $event);
|
||
}
|
||
~~~
|
||
|
||
где `$event` — это экземпляр класса [CEvent] или производного от него,
|
||
представляющего параметр события. К событию можно подключить обработчик как показано ниже:
|
||
|
||
~~~
|
||
[php]
|
||
$component->onClicked=$callback;
|
||
~~~
|
||
|
||
где `$callback` — это корректный callback-вызов PHP (см.
|
||
PHP-функцию call_user_func). Это может быть либо глобальная функция, либо метод класса.
|
||
В последнем случае вызову должен передаваться массив: `array($object,'methodName')`.
|
||
|
||
Обработчик события должен быть определён следующим образом:
|
||
|
||
~~~
|
||
[php]
|
||
function methodName($event)
|
||
{
|
||
…
|
||
}
|
||
~~~
|
||
|
||
где `$event` — это параметр, описывающий событие (передаётся методом `raiseEvent()`).
|
||
Параметр `$event` — это экземпляр класса [CEvent] или его производного.
|
||
Как минимум, он содержит информацию о том, кто вызвал событие.
|
||
|
||
Обработчик события может быть анонимной функцией,
|
||
требующей наличия версии PHP 5.3+. Например,
|
||
|
||
~~~
|
||
[php]
|
||
$component->onClicked=function($event) {
|
||
…
|
||
}
|
||
~~~
|
||
|
||
Если теперь использовать метод `onClicked()`, то в нём будет вызвано событие `onClicked`.
|
||
Назначенный ему обработчик будет запущен автоматически.
|
||
|
||
Событию могут быть назначены несколько обработчиков.
|
||
При возникновении события обработчики будут вызваны в порядке их назначения.
|
||
Если в обработчике необходимо предотвратить вызов последующих обработчиков,
|
||
необходимо установить [$event->handled|CEvent::handled] в `true`.
|
||
|
||
|
||
Поведения компонента
|
||
---------------------
|
||
|
||
Для компонентов реализован шаблон проектирования [mixin](http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%81%D1%8C_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)),
|
||
что позволяет присоединить к ним одно или несколько поведений. *Поведение* —
|
||
объект, чьи методы «наследуются» компонентом, к которому он присоединён. Под
|
||
«наследованием» здесь понимается наращивание функционала, а не наследование
|
||
в классическом смысле. К компоненту можно прикрепить несколько поведений и,
|
||
таким образом, получить аналог множественного наследования.
|
||
|
||
Поведения классов должны реализовывать интерфейс [IBehavior]. Большинство поведений могут быть созданы путём расширения
|
||
базового класса [CBehavior]. В случае если поведение необходимо прикрепить к [модели](/doc/guide/basics.model), его можно
|
||
создать на основе класса [CModelBehavior] или класса [CActiveRecordBehavior], которые реализуют дополнительные,
|
||
специфические для моделей, возможности.
|
||
|
||
Чтобы использовать поведение, его необходимо прикрепить к компоненту путём вызова метода поведения
|
||
[attach()|IBehavior::attach]. После этого мы можем вызывать методы поведения через компонент:
|
||
|
||
~~~
|
||
[php]
|
||
// $name уникально идентифицирует поведения в компоненте
|
||
$component->attachBehavior($name,$behavior);
|
||
// test() является методом $behavior
|
||
$component->test();
|
||
~~~
|
||
|
||
К прикреплённому поведению можно обращаться как к обычному свойству компонента.
|
||
Например, если поведение с именем `tree` прикреплено к компоненту, мы можем получить
|
||
ссылку на объект поведения следующим образом:
|
||
|
||
~~~
|
||
[php]
|
||
$behavior=$component->tree;
|
||
// эквивалентно выражению:
|
||
// $behavior=$component->asa('tree');
|
||
~~~
|
||
|
||
Поведение можно временно деактивировать, чтобы его методы и свойства были недоступны через компонент.
|
||
Например:
|
||
|
||
~~~
|
||
[php]
|
||
$component->disableBehavior($name);
|
||
// выражение ниже приведет к вызову исключения
|
||
$component->test();
|
||
$component->enableBehavior($name);
|
||
// здесь все будет работать нормально
|
||
$component->test();
|
||
~~~
|
||
|
||
В случае когда два поведения, прикреплённые к одному компоненту, имеют методы с одинаковыми именами,
|
||
преимущество будет иметь метод поведения, прикреплённого раньше.
|
||
|
||
Использование поведений совместно с [событиями](/doc/guide/basics.component#component-event) даёт дополнительные возможности.
|
||
Поведение, прикреплённое к компоненту, может назначать некоторые свои методы в качестве обработчиков событий компонента.
|
||
В этом случае поведение получает возможность следить за ходом работы компонента и даже изменять его.
|
||
|
||
Свойства поведения также доступны из компонента, к которому оно присоединено.
|
||
Свойства включают в себя как открытые поля класса поведения, так и его методы чтения/записи (getters/setters).
|
||
Например, если поведение имеет свойство с именем `xyz` и привязано к компоненту
|
||
`$a`, то мы можем использовать выражение `$a->xyz` для доступа к этому свойству. |