Modelo de componentes
Un concepto importante en Nette es el de componente. Insertamos componentes visuales interactivos en páginas, formularios o todos sus
elementos son también componentes. Hay dos clases básicas de las que heredan todos estos componentes, forman parte del paquete
nette/component-model
y se encargan de crear la jerarquía del árbol de componentes.
Component
Nette\ComponentModel\Component
es el ancestro común de todos los componentes. Contiene el método getName()
que devuelve el nombre del componente y
el método getParent()
que devuelve su padre. Ambos pueden establecerse con el método setParent()
–
el primer parámetro es el padre y el segundo es el nombre del componente.
lookup (string $type): ?Component
Busca en la jerarquía un objeto de la clase o interfaz deseada. Por ejemplo,
$component->lookup(Nette\Application\UI\Presenter::class)
devuelve presentador si el componente está conectado a
él, a pesar de varios niveles.
lookupPath (string $type): ?string
Devuelve la llamada ruta, que es una cadena formada por la concatenación de los nombres de todos los componentes de la ruta
entre el componente actual y el componente buscado. Así, por ejemplo,
$component->lookupPath(Nette\Application\UI\Presenter::class)
devuelve el identificador único del componente
relativo al presentador.
Container
Nette\ComponentModel\Container
es el componente padre, es decir, el componente que contiene a los hijos y, por tanto, forma la estructura de árbol. Dispone de
métodos para añadir, recuperar y eliminar componentes fácilmente. Es el ancestro de, por ejemplo, el formulario o las clases
Control
y Presenter
.
getComponent (string $name): ?Component
Devuelve un componente. El intento de llamar a un hijo no definido provoca la invocación de la fábrica createComponent($nombre).
El método createComponent($name)
invoca el método createComponent<component name>
en el
componente actual y pasa el nombre del componente como parámetro. El componente creado se pasa al componente actual como hijo.
Llamamos a estas fábricas de componentes, pueden ser implementadas en clases heredadas de Container
.
getComponents(): array
Devuelve los descendientes directos como una matriz. Las claves contienen los nombres de estos componentes. Nota: en la versión 3.0.x, el método devolvía un iterador en lugar de un array, y su primer parámetro especificaba si iterar a través de los componentes en profundidad, y el segundo representaba un filtro de tipo. Estos parámetros están obsoletos.
getComponentTree(): array
Devuelve toda la jerarquía de componentes, incluidos todos los componentes hijos anidados como matriz indexada. La búsqueda va primero en profundidad.
Supervisión de antepasados
El modelo de componentes de Nette permite trabajar con árboles muy dinámicos (podemos eliminar, mover, añadir componentes), por lo que sería un error confiar en el hecho de que después de crear un componente, el padre, el padre del padre, etc. se conocen inmediatamente (en el constructor). Normalmente el padre no se conoce en absoluto cuando se crea el componente.
¿Cómo saber cuándo se ha añadido un componente al árbol del presentador? No basta con hacer un seguimiento del cambio de
padre, porque el padre del padre podría haber sido adjuntado al presentador, por ejemplo. El método monitor($type, $attached,
$detached) puede ayudar. Cada componente puede monitorizar cualquier número de clases e interfaces. La conexión
o desconexión se anuncia llamando a las llamadas de retorno $attached
y $detached
, respectivamente, y
pasando el objeto de la clase monitorizada.
Un ejemplo: La clase UploadControl
, que representa el elemento de formulario para subir archivos en Nette Forms,
tiene que establecer el atributo del formulario enctype
al valor multipart/form-data
. Pero en el momento
de la creación del objeto no tiene que estar unido a ningún formulario. ¿Cuándo modificar el formulario? La solución es
simple – creamos una solicitud de control en el constructor:
class UploadControl extends Nette\Forms\Controls\BaseControl
{
public function __construct($label)
{
$this->monitor(Nette\Forms\Form::class, function ($form): void {
$form->setHtmlAttribute('enctype', 'multipart/form-data');
});
// ...
}
// ...
}
y cuando el formulario está disponible, se llama al callback. (Anteriormente, se utilizaban en su lugar los métodos comunes
attached
y detached
).