Nette\Component
Jádrem aplikací v Nette jsou komponenty. Komponenta není nic jiného,
než objekt implementující rozhraní Nette\IComponent. To po
objektu vyžaduje metodu vracející jméno komponenty getName(),
což je libovolný řetězec, a rodičovský objekt getParent().
Dále je tu metoda pro nastavení obojího setParent().
Spojení s rodičovskou
komponentou tvoří základ hierarchie. Rodičovská komponenta kromě
rozhraní Nette\IComponent implementuje
i Nette\IComponentContainer, které obsahuje metody pro přidání,
odebrání, získání a iteraci nad komponentami. (TODO: je otázka, jestli
toto neimplementovat přímo jako ArrayAccess + getIterator, má to svá pro
i proti). Celý strom komponent je tedy tvořen větvemi v podobě
objektů Nette\IComponentContainer a listů
Nette\IComponent.
Připravenou implementací jsou pak třídy Nette\Component a Nette\ComponentContainer.
Z Nette\Component vycházejí všechny prvky formulářů,
Nette\ComponentContainer je zase základem pro samotný formulář
a třídy v Nette\Application jako PresenterComponent,
Control a Presenter.
Hledá se rodič!
Nette\Component disponuje několika užitečnými metodami:
Nette\Component::lookup($type) vyhledá v hierarchii směrem
nahoru objekt požadované třídy nebo rozhraní. Například
$component->lookup('Nette\Application\Presenter') vrací
presenter, pokud je k němu, i přes několik úrovní, komponenta
připojena.
Blízkou metodou je Nette\Component::lookupPath($type), která
vrací tzv. cestu, což řetězec vzniklý spojením jmen všech komponent na
cestě mezi aktuální a hledanou komponentou. Takže např.
$component->lookupPath('Nette\Application\Presenter') vrací
jedinečný identifikátor komponenty vůči presenteru.
Monitorování změn
Jak poznat, kdy byla komponenta připojena do stromu presenteru? Sledovat
změnu rodiče nestačí, protože k presenteru mohl být připojen třeba
rodič rodiče. Pomůže metoda Nette\Component::monitor($type).
Každá komponenta může monitorovat libovolný počet tříd/rozhraní.
Připojení nebo odpojení je ohlášeno zavoláním metody
attached($obj) resp. detached($obj), kde
$obj je objekt sledované třídy.
Pro lepší pochopení příklad: třída FileUpload,
reprezentující formulářový prvek pro upload souborů v Nette\Forms, musí
formuláři nastavit atribut enctype na hodnotu
multipart/form-data. V době vytvoření objektu ale k žádnému
formuláři připojena být nemusí (leda by se v konstruktoru předal $parent,
ale ani ten nemusí být formulářem či kontejnerem připojeným
k formuláři). Ve kterém okamžiku tedy formulář modifikovat? Řešení je
jednoduché – v konstruktoru se požádá o monitoring:
class FileUpload extends FormControl
{
public function __construct($label)
{
$this->monitor('Nette\Forms\Form');
...
}
a jakmile je formulář k dispozici, zavolá se metoda attached:
protected function attached($form)
{
if ($form instanceof Form) {
$form->getElementPrototype()->enctype = 'multipart/form-data';
}
}
Monitorování a dohledávání komponent nebo cest přes lookup je velmi pečlivě optimalizované pro maximální výkon.
Viz také:



