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 ).

versión: 3.x