Nette Documentation Preview

syntax
Modelo do componente
********************

.[perex]
Um conceito importante em Nette é o componente. Inserimos [componentes visuais interativos |application:components] 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
=========
[api: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 .[method]
------------------------------------------
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 .[method]
-------------------------------------------
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
=========
[api: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 .[method]
------------------------------------------------
Devolve um componente. Tentativa de chamar de criança indefinida causa invocação de fábrica [criarComponente($nome) |api:Nette\ComponentModel\Container::createComponent()]. 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 .[method]
--------------------------------
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 .[method]{data-version:3.1.0}
-------------------------------------------------------
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 .[#toc-monitoring-of-ancestors]
===========================================================

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) |api:Nette\ComponentModel\Component::monitor()] 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:

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


{{leftbar: nette:@menu-topics}}

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