Modelo do componente

Um conceito importante em Nette é o componente. Inserimos componentes visuais interativos em páginas, formulários ou todos os seus elementos são também componentes. Há duas classes básicas das quais todos esses componentes herdam, fazem parte do pacote nette/component-model e são responsáveis pela criação da hierarquia da árvore de componentes.

Component

Nette\ComponentModel\Component é o ancestral comum de todos os componentes. Ele contém o método getName() devolvendo o nome do componente e o método getParent() devolvendo seu pai. Ambos podem ser definidos com o método setParent() – o primeiro parâmetro é o pai e o segundo é o nome do componente.

lookup(string $type): ?Component

Procura na hierarquia por um objeto da classe ou interface desejada. Por exemplo, $component->lookup(Nette\Application\UI\Presenter::class) retorna apresentador se o componente estiver conectado a ele, apesar de vários níveis.

lookupPath(string $type): ?string

Retorna o chamado caminho, que é uma cadeia formada por concatenar os nomes de todos os componentes no caminho entre o componente atual e o componente que está sendo procurado. Assim, por exemplo, $component->lookupPath(Nette\Application\UI\Presenter::class) retorna o identificador único do componente em relação ao apresentador.

Container

Nette\ComponentModel\Container é o componente pai, ou seja, o componente que contém as crianças e assim formando a estrutura em árvore. Possui métodos para facilmente adicionar, recuperar e remover componentes. É o ancestral, por exemplo, da forma ou classes Control e Presenter.

getComponent(string $name): ?Component

Devolve um componente. Tentativa de chamar de criança indefinida causa invocação de fábrica criarComponente($nome). Método createComponent($name) invoca método createComponent<component name> no componente atual e ele passa o nome do componente como parâmetro. O componente criado é então passado para o componente atual como seu filho. Chamamos essas fábricas de componentes, elas podem ser implementadas em classes herdadas de Container.

getComponents(): array

Retorna os descendentes diretos como uma matriz. As chaves contêm os nomes desses componentes. Observação: na versão 3.0.x, o método retornava um iterador em vez de uma matriz, e seu primeiro parâmetro especificava se deveria iterar pelos componentes em profundidade, e o segundo representava um filtro de tipo. Esses parâmetros estão obsoletos.

getComponentTree(): array

Retorna toda a hierarquia de componentes, inclusive todos os componentes filhos aninhados, como uma matriz indexada. A pesquisa é feita primeiro em profundidade.

Monitoramento de Ancestrais

O modelo de componentes Nette permite um trabalho em árvore muito dinâmico (podemos remover, mover, adicionar componentes), portanto seria um erro confiar no fato de que, depois de criar um componente, o pai, o pai da mãe, etc. são conhecidos imediatamente (no construtor). Normalmente, o pai não é conhecido de forma alguma quando o componente é criado.

Como descobrir quando um componente foi adicionado à árvore apresentadora? Não basta acompanhar a mudança dos pais, porque os pais dos pais poderiam ter sido anexados ao apresentador, por exemplo. O método do monitor ($type, $attached, $detached) pode ajudar. Cada componente pode monitorar qualquer número de classes e interfaces. A conexão ou desconexão é anunciada ligando para $attached e $detached, respectivamente, e passando o objeto da classe monitorada.

Um exemplo: A classe UploadControl, que representa o elemento do formulário para carregar arquivos nos Formulários Nette, tem que definir o atributo do formulário enctype para valorizar multipart/form-data. Mas no momento da criação do objeto, ele não precisa ser anexado a nenhum formulário. Quando modificar o formulário? A solução é simples – nós criamos um pedido de monitoramento no construtor:

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');
		});
		// ...
	}

	// ...
}

e quando o formulário está disponível, a ligação de retorno é chamada. (Anteriormente, os métodos comuns attached e detached eram usados em seu lugar).

versão: 3.x