Volani komponenty v komponente
- Willik
- Člen | 19
Prosim o radu, jak v komponente, ktera vypisuje ve foreach nejake kategorie volat jinou komponentu, ktera vypise nekolik polozek z dane kategorie.
Situace je tato:
do sablony presenteru vkladam komponentu pro vypis kategorii
{control subSectionList}
subSectionList obsahuje zhruba:
{foreach $items as $item}
<h3>{$item['caption']}</h3>
{control testsList,$item['cat']}
{/foreach}
testsList komponenta pak vypise par polozek pro kazdou kategorii
{foreach $items as $item}
<li>{$item['polozka']}</li>
{/foreach}
komponenta subSectionList ale nezna testsList, takze to skonci chybou
zkusil jsem reseni pres
{php $this->getParameter('presenter')->getComponent('testsList')->render($item['cat'])}
to funguje, ale neprijde mi to jako nejlepsi reseni
Za rady predem dekuju.
- Willik
- Člen | 19
zkousim to pres tovarnicky, v presenteru mam createComponentSubSectionList a createComponentTestsList a a v nich pak volani new TemplateListControl() resp. new TemplateTestsListControl()
myslenak byla takova, ze ten control SubSectionList bude podle pouzite sablony vypisovat bud jen samotne kategorie, nebo treba tech par polozek ap. – ze o tom co se zobrazi rozhodne to co je v sablone – nekdy bude sablona jen pro vypis samotnych kategorii, na jinem miste ke kategoriim budu vypisovat i par polozek …
Editoval Willik (24. 10. 2016 15:31)
- Jan Mikeš
- Člen | 771
To proto, že ty komponenty o sobě navzájem neví. Buď můžeš využít více view v komponentě, např takto:
{control sectionList}
{control sectionList:withSubList}
Pak si nadefinuješ v komponentě
public function renderWithSubList() { }
A ta se bude volat pro druhý uvedený zápis.
Nebo mít komponentu v komponentě.
- Willik
- Člen | 19
Dekuju.
Je nekde neco vic k te komponente v komponente? Treba nejaka ukazka. Zkousel
jsem k tomu neco najit,ale bud jsem hledal spatne, nebo to neni moc
popsane.
Nemam s tim moc zkusenosti, proto jeste jedna otazka – ktere reseni by se pro uvedeny pripad podle vas hodilo lepe?
- Eda
- Backer | 220
Ten příklad, co jsi uvedl v úvodním příspěvku, ti nefungoval proto,
že ty jsi v šabloně komponenty subSectionList.latte
volal
{control testsList ...}
, což se přeložilo jako volání metody
getComponent('testsList')
na instanci komponenty, které patřila
ta šablona – tzn. SubSectionList
. To pak hledalo metodu
createComponentTestsList
v té třídě
SubSectionList
, tam ale žádná není, proto to spadlo.
Tzn. obecně, když chceš vytvořit komponentu v komponentě, musíš do
té komponenty dát tovární metody createComponentXY
, aby ti to
fungovalo. To, že takovou metodu máš v presenteru, danou komponentu
nezajímá, protože o tom vůbec neví (a je to dobře).
Doporučuju tedy přidat tu metodu createComponentTestsList
do
komponenty SubSectionList
a bude ti to fungovat.
Ještě poznámka k další věci: předáváš do té komponenty
TestsList
parametr přes render
metodu (to
{control testsList, $item['cat']}
zavolá metodu
render
s a předá ji přes parametr tu hodnotu
$item['cat']
). To je ale antipatern. Zkus se tomu vyhnout a
použít radši Multiplier.
Důsledek (nevím, jestli chtěný) navíc je, že se vytvoří jen jedna
instance komponenty TestsList
a na ní se pro každý výpis volá
znovu render
metoda, akorát s jiným parametrem. Logicky by to
ale možná mělo být spíš tak, že to budou samostatné instance komponent
pro každý jeden výpis. Ale to už záleží na konkrétním use-casu.
Editoval Eda (24. 10. 2016 16:43)
- Willik
- Člen | 19
Dekuju,
jdu se podivat na tu komponentu v komponente. jestli jsem tomu dobre porozumel,
tak jde o presunuti z presenteru (ktery je taky vlastne komponenta) primo do
te komponenty.
K tomu mam jeste jeden dotaz – do komponenty je lepsi predavat zavislosti
pres konstruktor nebo pres inject?
- Jan Mikeš
- Člen | 771
@Willik vhodnější je přes konstruktor a vytvářet si na
komponenty factories (můžeš využít i nette generované factories přes
interface – což je mimochodem pěkně popsané
tady) to ti zajistí, že nebudeš muset ručně psát
new XyComponent(.., ..)
a vypisovat všechny závislosti, ale
automaticky přes DI se ti tam vloží.
Editoval Jan Mikeš (24. 10. 2016 17:55)