Volani komponenty v komponente

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Willik
Člen | 19
+
-1
-

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.

Jan Mikeš
Člen | 771
+
0
-

Jak a kde vytváříš ty komponenty? Pokud obě vytváříš v presenteru tak o sobě vzájemně neví. Můžeš si vytvořit komponentu v komponentě nebo navíc využít multiplieru což by možná bylo i vhodnějším řešením než používat parametry.

Willik
Člen | 19
+
0
-

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
+
0
-

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
+
0
-

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
+
+2
-

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
+
0
-

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
+
+2
-

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

Willik
Člen | 19
+
0
-

Jeste jednou vsem dekuji a jdu se s tim poprat podle uvedenych rad. :-)

Editoval Willik (25. 10. 2016 10:32)