Component
=========

Las aplicaciones Yii se construyen con componentes que son objetos sujetos a una especificación. Un componente es una instancia de [CComponent] o de una de sus clases derivadas. Usar un componente implica básicamente acceder a sus propiedades y levantar/manejar sus eventos. La clase base [CComponent] especifica cómo definir propiedades y eventos.

Propiedeades de Component
-------------------------

Una propiedad de un componente es como una variable miembro pública de un objeto. Podemos leer su valor o asignarle un valor. Por ejemplo:

~~~
[php]
$width=$component->textWidth;     // leer la propiedad textWidth
$component->enableCaching=true;   // escribir la propiedad enableCaching
~~~

Para definir una propiedad de componente, podemos simplemente declarar un variable miembro pública en la clase del componente. Un método más flexible es definir métodos getters y setters como estos:

~~~
[php]
public function getTextWidth()
{
    return $this->_textWidth;
}

public function setTextWidth($value)
{
    $this->_textWidth=$value;
}
~~~

El código de arriba define una propiedad editable de nombre `textWidth` (el nombre no es sensible a mayúsculas). Para leer la propiedad, invocamos a `getTextWidth()`, cuyo valor devuelto corresponde al valor de la propiedad; de igual forma, para escribir la propiedad, invocamos a `setTextWidth()`. Si no se ha definido el método setter, la propiedad será de sólo lectura e intentar editarla arrojará una excepción. El uso de métodos getter y setter para definir una propiedad tiene la ventaja de que puede ejecutarse lógica adicional (p. ej. validar, levantar eventos, etc.) al leer o escribir la propiedad.

>Note|Nota: Hay una ligera diferencia entre una propiedad definida mediante métodos getter/setter y una variable miembro de clase. El nombre de la primera no es sensible a mayúsculas/minúsculas y el de la última sí lo es.

Evento de Component
-------------------

Los eventos de componente son propiedades especiales que toman métodos (que se llaman `manejadores de eventos`) como valores. Asignar un método a un evento hará que se invoque al método automáticamente en los lugares en los que se levanta el evento. Por tanto, el comportamiento de un componente puede modificarse de forma que no pueda anticiparse durante el desarrollo del componente.

Definimos un evento de componente definiendo un método cuyo nombre comienza con `on`. Como los nombres de propiedades definidos mediante métodos setter/getter, los nombres de los eventos no son sensibles a mayúsculas. El código siguiente define el evento `onClicked`:

~~~
[php]
public function onClicked($event)
{
	$this->raiseEvent('onClicked', $event);
}
~~~

donde `$event` es una instancia de [CEvent] o de una clase derivada que representa el parámetro del evento.

Podemos asignar un método a este evento como sigue:

~~~
[php]
$component->onClicked=$callback;
~~~

donde `$callback` se refiere a una retrollamada PHP válida. Puede ser una función global o un método de clase. Si es esto último, la retrollamda ha de darse como un array: `array($object,'methodName')`.

La signatura de un manejador de eventos ha de ser como sigue:

~~~
[php]
function methodName($event)
{
    ......
}
~~~

donde `$event` es el parámetro que describe el evento (se origina en la llamada a `raiseEvent()`). El parámetro `$event` es una instancia de [CEvent] o de una clase derivada. Como mínimo, ha de contener la información sobre quién levantó el evento.
Un manejador de eventos también puede ser una función anónima que está soportada en PHP 5.3 o posterior. Por ejemplo:


~~~
[php]
$component->onClicked=function($event) {
	......
}
~~~

Si llamamos a `onClicked()` ahora, el evento `onClicked` será levantado (dentro de `onClicked()`) y el manejador de eventos asignado será invocado automáticamente.

A un evento se le pueden asignar múltiples manejadores. Cuando se levanta el evento, los manejadores serán invocados en el orden en que estén asignados al evento. Si un manejador decide evitar que se invoque al resto de manejadores, puede poner [$event->handled|CEvent::handled] a true.



Comportamiento de Component
---------------------------

Un componente soporta el patrón [mixin](http://en.wikipedia.org/wiki/Mixin)y puede ser asignado a uno o varios comportamientos (behaviors). Un *comportameinto* es un objeto cuyos métodos pueden ser 'heredados' por su componente asignado mediante colección de funcionalidad en vez de especialización (es decir, herencia normal de clase). A un componente pueden asignársele varios comportamientos y por tanto, alcanzar 'herencia múltiple'.

Las clases comportamiento han de implementar la interfaz [IBehavior]. La mayoría de los comportamientos pueden extender a partir de la clase base [CBehavior]. Si un comportamiento tiene que asignarse a un [model](/doc/guide/basics.model), también puede extender de [CModelBehavior] o [CActiveRecordBehavior] que implementa funcionalidades adicionales específicas de los modelos.

Para usar un comportamiento, ha de estar asignado a un componente primero, llamando al método [attach()|IBehavior::attach] del comportamiento. Luego podremos llamar a un método del comportamiento a través del componente:

~~~
[php]
// $name identifica unívocamente al comportamiento en el componente
$component->attachBehavior($name,$behavior);
// test() es un método de $behavior
$component->test();
~~~

Un comportamiento asignado puede accederse como una propiedad normal del componente. Por ejemplo, si un comportamiento llamado `tree` está asignado a un componente, podemos obtener la referencia a este objeto comportamiento usando:

~~~
[php]
$behavior=$component->tree;
// equivalente a lo siguiente:
// $behavior=$component->asa('tree');
~~~

Un comportamiento puede ser temporalmente deshabilitado de modo que sus métodos no estén disponibles desde el componente.
Por ejemplo,

~~~
[php]
$component->disableBehavior($name);
// el siguiente comando lanzará una excepción
$component->test();
$component->enableBehavior($name);
// ahora sí funciona
$component->test();
~~~

Es posible que dos comportamientos asignados al mismo componente tengan métodos con el mismo nombre. En este caso, el método del primer comportamiento asignado tendrá preferencia.

Cuando se usan juntos con [events](/doc/guide/basics.component#component-event), los componentes son aún más potentes. Un comportamiento, cuando está asignado a un componente, puede asignar algunos de sus métodos a algunos eventos del componente. Con esto, el comportamiento puede observar o cambiar el flujo normal de ejecución del componente.

Las propiedades de un comportamiento también pueden accederse a través del componente al que está asignado. Las propiedades incluyen tanto las variables miembro públicas como las propiedades definidas mediante getters y setters del comportamiento. Por ejemplo, si un comportamiento tiene una propiedad llamada `xyz` y el comportamiento está asignado a un componente `$a`, entonces podemos usar la expresión `$a->xyz` para acceder a la propiedad del comportamiento.

<div class="revision">$Id$</div>
