Komponens modell

A Nette fontos fogalma a komponens. Az oldalakra vizuális interaktív komponenseket illesztünk be, komponensek az űrlapok vagy azok összes eleme is. A két alapvető osztály, amelyektől ezek a komponensek öröklődnek, a nette/component-model csomag részét képezik, és feladatuk a komponensek fa hierarchiájának létrehozása.

Component

Az Nette\ComponentModel\Component az összes komponens közös őse. Tartalmazza a getName() metódust, amely visszaadja a komponens nevét, és a getParent() metódust, amely visszaadja a szülőjét. Mindkettőt a setParent() metódussal lehet beállítani – az első paraméter a szülő, a második a komponens neve.

lookup (string $type): ?Component

Felkeresi a hierarchiában felfelé a kívánt osztály vagy interfész objektumát. Például a $component->lookup(Nette\Application\UI\Presenter::class) visszaadja a presentert, ha a komponens hozzá van csatolva, akár több szinten keresztül is.

lookupPath (string $type): ?string

Visszaadja az úgynevezett utat, amely egy string, ami az aktuális és a keresett komponens közötti útvonalon lévő összes komponens nevének összekapcsolásával jön létre. Tehát pl. a $component->lookupPath(Nette\Application\UI\Presenter::class) visszaadja a komponens egyedi azonosítóját a presenterhez képest.

Container

Az Nette\ComponentModel\Container a szülő komponens, azaz a leszármazottakat tartalmazó komponens, amely fa struktúrát alkot. Metódusokkal rendelkezik az objektumok egyszerű hozzáadásához, lekéréséhez és eltávolításához. Például az űrlap vagy a Control és Presenter osztályok őse.

getComponent (string $name): ?Component

Visszaadja a komponenst. Egy nem definiált leszármazott lekérésekor a createComponent($name) factory hívódik meg. A createComponent($name) metódus meghívja az aktuális komponensben a createComponent<komponens neve> metódust, és paraméterként átadja neki a komponens nevét. A létrehozott komponens ezután hozzáadódik az aktuális komponenshez annak leszármazottjaként. Ezeket a metódusokat komponens factory-knak nevezzük, és a Container osztály leszármazottai implementálhatják őket.

getComponents(): array

Visszaadja a közvetlen leszármazottakat tömbként. A kulcsok ezeknek a komponenseknek a neveit tartalmazzák. Megjegyzés: a 3.0.x verzióban a metódus tömb helyett iterátort adott vissza, és az első paramétere határozta meg, hogy a komponenseket mélységében kell-e bejárni, a második pedig egy típus szűrőt jelentett. Ezek a paraméterek elavultak.

getComponentTree(): array

Lekéri a teljes komponens hierarchiát, beleértve az összes beágyazott alárendelt komponenst is, indexelt tömbként. A keresés először mélységében történik.

Ősök monitorozása

A Nette komponens modellje nagyon dinamikus munkát tesz lehetővé a fával (komponenseket kivehetünk, áthelyezhetünk, hozzáadhatunk), ezért hiba lenne arra támaszkodni, hogy a komponens létrehozása után azonnal (a konstruktorban) ismert a szülő, a szülő szülője stb. Legtöbbször ugyanis a szülő a létrehozáskor egyáltalán nem ismert.

Hogyan lehet tudni, mikor csatlakozott a komponens a presenter fájához? A szülő változásának figyelése nem elegendő, mert a presenterhez például a szülő szülője is csatlakozhatott. Segít a monitor($type, $attached, $detached) metódus. Minden komponens tetszőleges számú osztályt és interfészt monitorozhat. A csatlakozást vagy leválasztást a $attached, illetve $detached callback meghívása jelzi, átadva a figyelt osztály objektumát.

A jobb megértés érdekében egy példa: az UploadControl osztály, amely a Nette Forms fájlfeltöltési űrlap elemét képviseli, be kell állítania az űrlap enctype attribútumát multipart/form-data értékre. Az objektum létrehozásakor azonban nem feltétlenül kell csatlakoznia semmilyen űrlaphoz. Melyik pillanatban kell tehát módosítani az űrlapot? A megoldás egyszerű – a konstruktorban kérjük a monitorozást:

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

	// ...
}

és amint az űrlap elérhetővé válik, a callback meghívódik. (Korábban helyette a közös attached, illetve detached metódust használták).

verzió: 3.x