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