Commit 6e87e1e2 by Marco Da Silva

Update concept-behaviors.md

parent 39e2c233
...@@ -10,47 +10,88 @@ comportamiento puede responder a [eventos](concept-events.md) disparados por el ...@@ -10,47 +10,88 @@ comportamiento puede responder a [eventos](concept-events.md) disparados por el
o adaptar a la ejecución normal del código del componente. o adaptar a la ejecución normal del código del componente.
Usando comportamientos <a name="using-behaviors"></a> Definiendo comportamientos <a name="defining-behaviors"></a>
---------------------- --------------------------
Para poder utilizar un comportamiento, primero tienes que unirlo a un [[yii\base\Component|componente]]. Describiremos cómo Para definir un comportamiento, se debe crear una clase que exiende [[yii\base\Behavior]], o se extiende una clase hija. Por ejemplo:
puedes vincular un comportamiento en la próxima sub-sección.
Una vez que el comportamiento ha sido vinculado a un componente, su uso es sencillo. ```php
namespace app\components;
Puedes usar a una variable *pública* o a una [propiedad](concept-properties.md) definida por un `getter` y/o un `setter` use yii\base\Behavior;
del comportamiento a través del componente con el que se ha vinculado, como por ejemplo,
```php class MyBehavior extends Behavior
// "prop1" es una propiedad definida en la clase comportamiento {
echo $component->prop1; public $prop1;
$component->prop1 = $value;
```
También puedes llamar métodos *públicos* del comportamiento de una forma similar, private $_prop2;
```php public function getProp2()
// bar() es un método público definido dentro de la clase comportamiento {
$component->bar(); return $this->_prop2;
}
public function setProp2($value)
{
$this->_prop2 = $value;
}
public function foo()
{
// ...
}
}
``` ```
El código anterior define la clase de comportamiento (behavior) app\components\MyBehavior`, con dos propiedades --
`prop1` y `prop2`--y un método `foo()`. Tenga en cuenta que la propiedad `prop2`
se define a través de la getter `getProp2()` y el setter `setProp2()`. Este caso es porque [[yii\base\Behavior]] extiende [[yii\base\Object]] y por lo tanto se apoya en la definición de [propiedades](concept-properties.md) via getters y setters.
Como puedes ver, aunque `$component` no tiene definida `prop1` y `bar()`, pueden ser usadas como si fueran parte Debido a que esta clase es un comportamiento, cuando está unido a un componente, el componente también tienen la propiedad `prop1` y `prop2` y el método `foo()`.
definida del componente.
Si dos comportamientos definen la misma propiedad o método y ambos están vinculados con el mismo componente, el > Consejo: Dentro de un comportamiento, puede acceder al componente que el comportamiento está unido a través de la propiedad [[yii\base\Behavior::owner]].
comportamiento que ha sido vinculado primero tendrá preferencia cuando se esté accediendo a la propiedad o método.
Un comportamiento puede estar asociado con un nombre cuando se une a un componente. Si este es el caso, es posible
acceder al objeto de comportamiento mediante el nombre, como se muestra a continuación, Gestión de eventos de componentes
---------------------------------
Si un comportamiento necesita responder a los acontecimientos desencadenados por el componente al que está unido, se debe reemplazar el método [[yii\base\Behavior::events()]]. Por ejemplo:
```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)
{
// ...
}
}
``` ```
También puedes acceder a todos los comportamientos vinculados al componente: El método [[yii\base\Behavior::events()|events()]] debe devolver una lista de eventos y sus correspondientes controladores.
El ejemplo anterior declara que el evento [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]] existe y esta exists y define su controlador, `beforeValidate()`. Al especificar un controlador de eventos, puede utilizar uno de los siguientes formatos:
* una cadena que se refiere al nombre de un método de la clase del comportamiento, como el ejemplo anterior
* un arreglo de objeto o nombre de clase, y un nombre de método como una cadena (sin paréntesis), ej., `[$object, 'methodName']`;
* una función anónima
La firma de un controlador de eventos debe ser la siguiente, donde `$ event` refiere al parámetro de evento. Por favor, consulte la sección [Eventos](concept-events.md) para más detalles sobre los eventos.
```php ```php
$behaviors = $component->getBehaviors(); function ($event) {
}
``` ```
...@@ -60,8 +101,8 @@ Vinculando Comportamientos <a name="attaching-behaviors"></a> ...@@ -60,8 +101,8 @@ Vinculando Comportamientos <a name="attaching-behaviors"></a>
Puedes vincular un comportamiento a un [[yii\base\Component|componente]] ya sea estática o dinámicamente. La primera forma Puedes vincular un comportamiento a un [[yii\base\Component|componente]] ya sea estática o dinámicamente. La primera forma
es la más comúnmente utilizada en la práctica. es la más comúnmente utilizada en la práctica.
Para unir un comportamiento estáticamente, reemplaza el método [[yii\base\Component::behaviors()|behaviors()]] de la Para unir un comportamiento estáticamente, reemplaza el método [[yii\base\Component::behaviors()|behaviors()]] dde la clase de componente a la que se une el comportamiento. El método [[yii\base\Component::behaviors()|behaviors()]] debe devolver una lista de comportamiento [configuraciones](concept-configurations.md).
clase componente que se está conectando. Por ejemplo, Cada configuración de comportamiento puede ser un nombre de clase de comportamiento o un arreglo de configuración:
```php ```php
namespace app\models; namespace app\models;
...@@ -74,20 +115,20 @@ class User extends ActiveRecord ...@@ -74,20 +115,20 @@ class User extends ActiveRecord
public function behaviors() public function behaviors()
{ {
return [ return [
// comportamiento anónimo, sólo el nombre de la clase del comportamiento // anonymous behavior, behavior class name only
MyBehavior::className(), MyBehavior::className(),
// comportamiento nombrado, sólo el nombre de la clase del comportamiento // named behavior, behavior class name only
'myBehavior2' => MyBehavior::className(), 'myBehavior2' => MyBehavior::className(),
// comportamiento anónimo, matriz de configuración // anonymous behavior, configuration array
[ [
'class' => MyBehavior::className(), 'class' => MyBehavior::className(),
'prop1' => 'value1', 'prop1' => 'value1',
'prop2' => 'value2', 'prop2' => 'value2',
], ],
// comportamiento nombrado, matriz de configuración // named behavior, configuration array
'myBehavior4' => [ 'myBehavior4' => [
'class' => MyBehavior::className(), 'class' => MyBehavior::className(),
'prop1' => 'value1', 'prop1' => 'value1',
...@@ -98,17 +139,13 @@ class User extends ActiveRecord ...@@ -98,17 +139,13 @@ class User extends ActiveRecord
} }
``` ```
El método [[yii\base\Component::behaviors()|behaviors()]] tiene que devolver la lista de los comportamientos
[configuraciones](concept-configurations.md).
Cada configuración de un comportamiento puede ser el nombre de la clase o una matriz de configuración.
Puedes asociciar un nombre a un comportamiento especificándolo en la clave de la matriz correspondiente a la configuración Puedes asociciar un nombre a un comportamiento especificándolo en la clave de la matriz correspondiente a la configuración
del comportamiento. En este caso, el comportamiento puede ser llamado un *comportamiento nombrado* (named behavior). En del comportamiento. En este caso, el comportamiento puede ser llamado un *comportamiento nombrado* (named behavior). En
el ejemplo anterior, hay dos tipos de comportamientos nombrados: `myBehavior2` y `myBehavior4`. Si un comportamiento el ejemplo anterior, hay dos tipos de comportamientos nombrados: `myBehavior2` y `myBehavior4`. Si un comportamiento
no está asociado con un nombre, se le llama *comportamiento anónimo* (anonymous behavior). no está asociado con un nombre, se le llama *comportamiento anónimo* (anonymous behavior).
Para vincular un comportamiento dinámicamente, llama al método [[yii\base\Component::attachBehavior()]] desde el componente al Para vincular un comportamiento dinámicamente, llama al método [[yii\base\Component::attachBehavior()]] desde el componente al
que se le va a unir el comportamiento. Por ejemplo, que se le va a unir el comportamiento:
```php ```php
use app\components\MyBehavior; use app\components\MyBehavior;
...@@ -126,19 +163,16 @@ $component->attachBehavior('myBehavior3', [ ...@@ -126,19 +163,16 @@ $component->attachBehavior('myBehavior3', [
'prop2' => 'value2', 'prop2' => 'value2',
]); ]);
``` ```
Puede vincular múltiples comportamientos a la vez mediante el uso del método [[yii\base\Component::attachBehaviors()]]. Por ejemplo,
You may attach multiple behaviors at once by using the [[yii\base\Component::attachBehaviors()]] method.
For example,
```php ```php
$component->attachBehaviors([ $component->attachBehaviors([
'myBehavior1' => new MyBehavior, // a named behavior 'myBehavior1' => new MyBehavior, // un comportamiento nombrado
MyBehavior::className(), // an anonymous behavior MyBehavior::className(), // un comportamiento anónimo
]); ]);
``` ```
También puedes asociar comportamientos a traves de [configuraciones](concept-configurations.md) compor el siguiente También puedes asociar comportamientos a traves de [configuraciones](concept-configurations.md) como el siguiente:
ejemplo. Para más detalles, por favor visita la sección [Configuraciones](concept-configurations.md#configuration-format).
```php ```php
[ [
...@@ -152,121 +186,73 @@ ejemplo. Para más detalles, por favor visita la sección [Configuraciones](conc ...@@ -152,121 +186,73 @@ ejemplo. Para más detalles, por favor visita la sección [Configuraciones](conc
] ]
``` ```
Para más detalles, por favor visita la sección [Configuraciones](concept-configurations.md#configuration-format).
Desasociar Comportamientos <a name="detaching-behaviors"></a>
--------------------------
Para desasociar un comportamiento, puedes llamar el método [[yii\base\Component::detachBehavior()]] con el nombre con el Usando comportamientos <a name="using-behaviors"></a>
que se le asoció: ----------------------
```php Para poder utilizar un comportamiento, primero tienes que unirlo a un [[yii\base\Component|componente]] según las instrucciones anteriores. Una vez que un comportamiento ha sido vinculado a un componente, su uso es sencillo.
$component->detachBehavior('myBehavior1');
```
También puedes desvincular *todos* los comportamientos: Puedes usar a una variable *pública* o a una [propiedad](concept-properties.md) definida por un `getter` y/o un `setter`
del comportamiento a través del componente con el que se ha vinculado:
```php ```php
$component->detachBehaviors(); // "prop1" es una propiedad definida en la clase comportamiento
echo $component->prop1;
$component->prop1 = $value;
``` ```
También puedes llamar métodos *públicos* del comportamiento de una forma similar:
Definiendo Comportamientos <a name="defining-behaviors"></a>
--------------------------
Para definir un comportamiento, crea una clase extendendiéndola de [[yii\base\Behavior]] o una de sus clases "hija". Por ejemplo,
```php ```php
namespace app\components; // foo() es un método público definido dentro de la clase comportamiento
$component->foo();
```
use yii\base\Model; Como puedes ver, aunque `$component` no tiene definida `prop1` y `bar()`, que se pueden utilizar como si son parte
use yii\base\Behavior; de la definición de componentes debido al comportamiento vinculado.
class MyBehavior extends Behavior Si dos comportamientos definen la misma propiedad o método y ambos están vinculados con el mismo componente, el
{ comportamiento que ha sido vinculado *primero* tendrá preferencia cuando se esté accediendo a la propiedad o método.
public $prop1;
private $_prop2;
public function getProp2()
{
return $this->_prop2;
}
public function setProp2($value) Un comportamiento puede estar asociado con un nombre cuando se une a un componente. Si este es el caso, es posible
{ acceder al objeto de comportamiento mediante el nombre, como se muestra a continuación,
$this->_prop2 = $value;
}
public function foo() ```php
{ $behavior = $component->getBehavior('myBehavior');
// ...
}
}
``` ```
El código anterior define la clase del comportamiento `app\components\MyBehavior` que provee dos propiedades `prop1` y También puedes acceder a todos los comportamientos vinculados al componente:
`prop2`, y un método `foo()` al componente con el que está asociado.
The above code defines the behavior class `app\components\MyBehavior` which will provide two properties
`prop1` and `prop2`, and one method `foo()` to the component it is attached to. Fíjese que la propiedad `prop2` esta
definida a través del getter `getProp2()` y el setter `setProp2()`. Esto es debido a que [[yii\base\Object]] es una
clase "ancestro" (o padre) de [[yii\base\Behavior]], la cual soporta la definición de [propiedades](concept-properties.md) por
getters/setters.
En un comportamiento, puedes acceder al componente al que está vinculado a través de la propiedad [[yii\base\Behavior::owner]].
Si un omportamiento necesita responder a los eventos que han sido disparados desde el componente al qu están asociados,
debería sobreescribir el método [[yii\base\Behavior::events()]]. Por ejemplo,
```php ```php
namespace app\components; $behaviors = $component->getBehaviors();
```
use yii\db\ActiveRecord;
use yii\base\Behavior;
class MyBehavior extends Behavior Desasociar Comportamientos <a name="detaching-behaviors"></a>
{ --------------------------
// ...
public function events() Para desasociar un comportamiento, puedes llamar el método [[yii\base\Component::detachBehavior()]] con el nombre con el
{ que se le asoció:
return [
ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
];
}
public function beforeValidate($event) ```php
{ $component->detachBehavior('myBehavior1');
// ...
}
}
``` ```
El método [[yii\base\Behavior::events()|events()]] tiene que devolver un listado de eventos y sus correspondientes También puedes desvincular *todos* los comportamientos:
controladores (handlers). El código anterior declara el evento [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]]
con su controlador `beforeValidate()`. Cuando se especifica un controlador de evento, pudes utilizar uno de los siguientes
formatos:
* una cadena que se refiere al nombre de un método de la clase comportamiento, como el ejemplo anterior;
* una matriz con un objeto o nombre de la clase, y el nombre de un método, por ejemplo, `[$object, 'nombreMétodo']`;
* una función anónima.
El formato de un controlador de eventos tendría que ser como se describe a continuación, donde `$event` se refiere al
parámetro `evento`. Por favor, visita la sección [Eventos](concept-events.md) para obtener más información acerca de
eventos.
```php ```php
function ($event) { $component->detachBehaviors();
}
``` ```
Utilizando `TimestampBehavior` <a name="using-timestamp-behavior"></a> Utilizando `TimestampBehavior` <a name="using-timestamp-behavior"></a>
----------------------------- -----------------------------
Para terminar, vamos a echar un vistazo a [[yii\behaviors\TimestampBehavior]] - un comportamiento que soporta de forma Para terminar, vamos a echar un vistazo a [[yii\behaviors\TimestampBehavior]]. Este comportamiento soporta de forma
automática la actualización de atributos `timestamp` (sellos de tiempo) de un [[yii\db\ActiveRecord|Registro Activo]] automática la actualización de atributos timestamp de un modelo [[yii\db\ActiveRecord|Registro Activo]]
(Active Record) cuando éste está siendo guardado. (Active Record) en cualquier momento donde se guarda el modelo (ej., en la inserción o actualización).
Primero, vincula este comportamiento a la clase [[yii\db\ActiveRecord|Active Record]] que desees utilizar. Primero, vincula este comportamiento a la clase [[yii\db\ActiveRecord|Active Record]] que desees utilizar.
...@@ -300,7 +286,7 @@ La configuración del comportamiento anterior especifica que ...@@ -300,7 +286,7 @@ La configuración del comportamiento anterior especifica que
* cuando el registro está siendo insertado, el comportamiento debe asignar el sello de tiempo actual a los atributos * cuando el registro está siendo insertado, el comportamiento debe asignar el sello de tiempo actual a los atributos
`created_at` y `updated_at`; `created_at` y `updated_at`;
* cuando el registro está siendo actualizado, el comportamiento debe asignar el sello de tiempo actual al atributo * cuando el registro está siendo actualizado, el comportamiento debe asignar el sello de tiempo actual al atributo
`updated_at. `updated_at`.
Ahora si tienes un objeto `User` e intentas guardarlo, descubrirás que sus campos `created_at` y `updated_at` están Ahora si tienes un objeto `User` e intentas guardarlo, descubrirás que sus campos `created_at` y `updated_at` están
automáticamente actualizados con el sello de tiempo actual: automáticamente actualizados con el sello de tiempo actual:
...@@ -313,8 +299,7 @@ echo $user->created_at; // muestra el sello tiempo actual (timestamp) ...@@ -313,8 +299,7 @@ echo $user->created_at; // muestra el sello tiempo actual (timestamp)
``` ```
El comportamiento [[yii\behaviors\TimestampBehavior|TimestampBehavior]] también ofrece un método muy útil llamado El comportamiento [[yii\behaviors\TimestampBehavior|TimestampBehavior]] también ofrece un método muy útil llamado
[[yii\behaviors\TimestampBehavior::touch()|touch()]], que asigna el sello de tiempo actual a un atributo especificado y [[yii\behaviors\TimestampBehavior::touch()|touch()]], que asigna el sello de tiempo actual a un atributo especificado y lo guarda automáticamente en la base de datos:
lo guarda automáticamente en la base de datos:
```php ```php
$user->touch('login_time'); $user->touch('login_time');
...@@ -326,13 +311,13 @@ Comparación con Traits <a name="comparison-with-traits"></a> ...@@ -326,13 +311,13 @@ Comparación con Traits <a name="comparison-with-traits"></a>
Mientras que los comportamientos son similares a [traits](http://www.php.net/traits) en cuanto que ambos "inyectan" sus Mientras que los comportamientos son similares a [traits](http://www.php.net/traits) en cuanto que ambos "inyectan" sus
métodos y propiedades a la clase primaria, son diferentes en muchos aspectos. Tal y como se describe abajo, los dos métodos y propiedades a la clase primaria, son diferentes en muchos aspectos. Tal y como se describe abajo, los dos
tienen sus ventajas y desventajas. Son much mejor descritos como complementos y no como reemplazos entre sí. tienen sus ventajas y desventajas. Son más como complementos el uno al otro en lugar de alternativas.
### Las Ventajas de los Comportamientos <a name="pros-for-behaviors"></a> ### Razones para utilizar comportamientos <a name="pros-for-behaviors"></a>
Las clases de comportamientos (Behaviors), como todas las clases, soportan herencias. Traits, por otro lado, pueden ser Las clases de comportamientos, como todas las clases, soportan herencias. Traits, por otro lado, pueden ser
considerados como un copia-y-pega de PHP. Los Traits no soportan la herencia de clases. considerados como un copia-y-pega de PHP. Ellos no soportan la herencia de clases.
Los comportamientos pueden ser asociados y desasociados a un componente dinámicamente sin necesidad de que la clase del Los comportamientos pueden ser asociados y desasociados a un componente dinámicamente sin necesidad de que la clase del
componente sea modificada. Para usar un trait, debes modificar la clase que la usa. componente sea modificada. Para usar un trait, debes modificar la clase que la usa.
...@@ -343,14 +328,13 @@ Los comportamientos pueden personalizar la ejecución de un componente al respon ...@@ -343,14 +328,13 @@ Los comportamientos pueden personalizar la ejecución de un componente al respon
Cuando hay un conflicto de nombre entre los diferentes comportamientos vinculados a un mismo componente, el conflicto es Cuando hay un conflicto de nombre entre los diferentes comportamientos vinculados a un mismo componente, el conflicto es
automáticamente resuelto respetando al que ha sido asociado primero. automáticamente resuelto respetando al que ha sido asociado primero.
El conflicto de nombres en traits requiere que manualmente sean resueltos cambiando el nombre de las propiedades o métodos El conflicto de nombres en traits requiere que manualmente sean resueltos cambiando el nombre de las propiedades o métodos afectados.
afectados.
### Las Ventajas de los Traits <a name="pros-for-traits"></a> ### Razones para utilizar los Traits <a name="pros-for-traits"></a>
Los Traits son mucho más eficientes que los comportamientos debido a que los últimos son objetos que consumen tiempo y Los Traits son mucho más eficientes que los comportamientos debido a que los últimos son objetos que consumen tiempo y
memoria. memoria.
Los IDEs (Programas de desarrollo) trabajan mucho mejor con traits ya que forman parte del lenguaje PHP. Los IDEs (Programas de desarrollo) son más amigables con traits ya que son una construcción del lenguaje nativo.
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