Modello di componente

Un concetto importante in Nette è quello di componente. Inseriamo componenti interattivi visivi nelle pagine, i moduli o tutti i loro elementi sono anch'essi componenti. Esistono due classi di base da cui ereditano tutti i componenti, che fanno parte del pacchetto nette/component-model e sono responsabili della creazione della gerarchia ad albero dei componenti.

Component

Nette\ComponentModel\Component è l'antenato comune di tutti i componenti. Contiene il metodo getName() che restituisce il nome del componente e il metodo getParent() che restituisce il suo genitore. Entrambi possono essere impostati con il metodo setParent(): il primo parametro è il genitore e il secondo è il nome del componente.

lookup(string $type): ?Component

Cerca nella gerarchia un oggetto della classe o dell'interfaccia desiderata. Ad esempio, $component->lookup(Nette\Application\UI\Presenter::class) restituisce presenter se il componente è collegato ad esso, nonostante i diversi livelli.

lookupPath(string $type): ?string

Restituisce il cosiddetto percorso, che è una stringa formata dalla concatenazione dei nomi di tutti i componenti del percorso tra il componente corrente e il componente cercato. Quindi, ad esempio, $component->lookupPath(Nette\Application\UI\Presenter::class) restituisce l'identificatore univoco del componente relativo al presentatore.

Container

Nette\ComponentModel\Container è il componente genitore, cioè il componente che contiene i figli e che quindi forma la struttura ad albero. Dispone di metodi per aggiungere, recuperare e rimuovere facilmente i componenti. È l'antenato, ad esempio, del modulo o delle classi Control e Presenter.

getComponent(string $name): ?Component

Restituisce un componente. Il tentativo di chiamare un figlio non definito causa l'invocazione del factory createComponent($nome). Il metodo createComponent($name) invoca il metodo createComponent<component name> nel componente corrente e passa il nome del componente come parametro. Il componente creato viene quindi passato al componente corrente come suo figlio. Questi factory di componenti possono essere implementati in classi ereditate da Container.

getComponents(): array

Restituisce i discendenti diretti come array. Le chiavi contengono i nomi dei componenti. Nota: nella versione 3.0.x, il metodo restituiva un iteratore invece di un array e il primo parametro specificava se iterare i componenti in profondità e il secondo rappresentava un filtro di tipo. Questi parametri sono deprecati.

getComponentTree(): array

Restituisce l'intera gerarchia di componenti, compresi tutti i componenti figli annidati, come array indicizzato. La ricerca va prima in profondità.

Monitoraggio degli antenati

Il modello dei componenti di Nette consente di lavorare in modo molto dinamico sull'albero (si possono rimuovere, spostare, aggiungere componenti), quindi sarebbe un errore fare affidamento sul fatto che dopo la creazione di un componente, il genitore, il genitore del genitore, ecc. siano noti immediatamente (nel costruttore). Di solito il genitore non è noto al momento della creazione del componente.

Come scoprire quando un componente è stato aggiunto all'albero del presentatore? Tenere traccia del cambiamento del genitore non è sufficiente, perché il genitore del genitore potrebbe essere stato aggiunto al presentatore, ad esempio. Il metodo monitor($type, $attached, $detached) può aiutare. Ogni componente può monitorare un numero qualsiasi di classi e interfacce. La connessione o la disconnessione vengono annunciate chiamando le callback $attached e $detached, rispettivamente, e passando l'oggetto della classe monitorata.

Un esempio: La classe UploadControl, che rappresenta l'elemento modulo per il caricamento dei file in Nette Forms, deve impostare l'attributo enctype del modulo sul valore multipart/form-data. Ma al momento della creazione dell'oggetto non deve essere collegata ad alcun modulo. Quando modificare il modulo? La soluzione è semplice: si crea una richiesta di monitoraggio nel costruttore:

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 il modulo è disponibile, viene richiamato il callback. (In precedenza, si usavano invece i metodi comuni attached e detached ).

versione: 3.x