Model komponente

Pomemben koncept v Nette je komponenta. Vizualne interaktivne komponente vstavljamo v strani, obrazci ali vsi njihovi elementi so prav tako komponente. Obstajata dva osnovna razreda, od katerih dedujejo vse te komponente, ki sta del paketa nette/component-model in sta odgovorna za ustvarjanje drevesne hierarhije komponent.

Komponenta

Nette\ComponentModel\Component je skupni prednik vseh komponent. Vsebuje metodo getName(), ki vrača ime komponente, in metodo getParent(), ki vrača njenega starša. Oba lahko nastavite z metodo setParent() – prvi parameter je starš, drugi pa ime komponente.

lookup(string $type): ?Component

V hierarhiji poišče objekt želenega razreda ali vmesnika. Na primer, $component->lookup(Nette\Application\UI\Presenter::class) vrne presenter, če je komponenta kljub več ravnem povezana z njim.

lookupPath(string $type): ?string

Vrne tako imenovano pot, ki je niz, sestavljen z združitvijo imen vseh komponent na poti med trenutno komponento in iskano komponento. Tako na primer $component->lookupPath(Nette\Application\UI\Presenter::class) vrne enolični identifikator komponente glede na predvajalnik.

Kontejner

Nette\ComponentModel\Container je nadrejena komponenta, tj. komponenta, ki vsebuje otroke in tako tvori drevesno strukturo. Ima metode za enostavno dodajanje, iskanje in odstranjevanje komponent. Je prednik na primer obrazca ali razredov Control in Presenter.

getComponent(string $name): ?Component

Vrne komponento. Poskus klica nedefiniranega otroka povzroči klic tovarne createComponent($name). Metoda createComponent($name) prikliče metodo createComponent<component name> v trenutni komponenti in ji kot parameter posreduje ime komponente. Ustvarjena komponenta se nato posreduje trenutni komponenti kot njen otrok. Te tovarne komponent imenujemo tovarne komponent, ki jih lahko implementiramo v razredih, podedovanih iz Container.

getComponents(): array

Vrne neposredne potomce kot polje. Ključi vsebujejo imena teh komponent. Opomba: v različici 3.0.x je metoda namesto polja vrnila iterator, njen prvi parameter pa je določal, ali naj se komponente iterira po globini, drugi pa je predstavljal filter tipa. Ta parametra sta zastarela.

getComponentTree(): array

Vrne celotno hierarhijo komponent, vključno z vsemi ugnezdenimi podrejenimi komponentami, kot indeksirano polje. Iskanje gre najprej v globino.

Spremljanje prednikov

Model komponent Nette omogoča zelo dinamično delo z drevesom (komponente lahko odstranjujemo, premikamo, dodajamo), zato bi bilo napačno, če bi se zanašali na to, da so po ustvarjanju komponente takoj (v konstruktorju) znani starši, starši staršev itd. Običajno starš ob ustvarjanju komponente sploh ni znan.

Kako ugotoviti, kdaj je bila komponenta dodana v drevo predstavitve? Spremljanje spremembe starša ni dovolj, saj bi bil lahko na primer starš starša priložen predstavniku. V pomoč je lahko metoda monitor($type, $attached, $detached). Vsaka komponenta lahko spremlja poljubno število razredov in vmesnikov. Priključitev ali odklop se najavi s klicem povratnih klicev $attached oziroma $detached, pri čemer se posreduje objekt spremljanega razreda.

Primer: Razred UploadControl, ki predstavlja element obrazca za nalaganje datotek v Nette Forms, mora nastaviti atribut obrazca enctype na vrednost multipart/form-data. Toda v času ustvarjanja objekta mu ni treba biti priključen na noben obrazec. Kdaj spremeniti obrazec? Rešitev je preprosta – v konstruktorju ustvarimo zahtevo za spremljanje:

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

	// ...
}

in ko je obrazec na voljo, se pokliče povratni klic. (Prej smo namesto tega uporabljali običajni metodi attached in detached.)

različica: 3.x