Data z komponenty do šablony presenteru
- Kcko
- Člen | 468
Ahoj,
dostal jsem se trošku do pasti.
Je Presenter A, komponenta B (nějaký výpis položek se stránkováním).
Presenter A vypisuje (defaultAction) nějaká svoje data plus někde dole na stránce komponentu B.
Nyní vznikla potřeba na místě nadpisu stránky (což je proměnná presenteru A) vypisovat data z komponenty B.
Naivně jsem si myslel, že by to mohlo jít přes událost takto:
Komponenta
<?php
public function renderDefault(array $config = [])
{
$config = $this->getCurrentConfig($config);
list($limit, $offset) = $this->getPages($config);
$this->template->advertisements = $this->model->getList(
$config,
$limit,
$offset
);
$this->template->config = $config;
**$this->onRender($this);**
$this->render($config);
}
?>
Presenter
<?php
$this->onRender['B'] = function ($control, $x) {
$this->template->x = $x;
};
?>
Ale pak jsem debugovaním zjistil, že komponenta se renderuje až dávno po po presenteru a nemám do jeho šablony jak dostat data.
Napadají mě jen 2 způsoby, oba mi přijdou hrozné ;-)
- Sáhnu si na metodu z komponenty, která vrací data pro onu proměnnou (počet výsledků), s tím, že v komponentě bude taky pro správný chod stránkování (akorát si to uvnitř zakešuji, aby se neprováděla zbytečně 2x).
- Výpíši si ten počet v komponetně a pak si to přes javascript vlepím na patřičná místa v šablona (správně k nadpisu presenteru).|
Nelze to nějak jinak?
Editoval Kcko (16. 3. 2023 9:06)
- Marek Znojil
- Člen | 90
Ahoj,
komponenty jsou lazy, takže si její vytvoření můžeš vynutit třeba v action metodě prezenteru:
public function actionDefault(): void{
$this['nazevKomponenty'];
}
Pak v nějaké události komponenty nebo *State metodě můžeš předpřipravit data, s kterými komponenta pracuje a geterem si je předat i do prezenteru.
Mohl bys i využít monitorování předků:
https://doc.nette.org/…ponent-model#…
Monitoring bys mohl předpřipravit v konstruktoru komponenty a předek, který by tě zajímal by byl Nette\Application\UI\Presenter.
- Kcko
- Člen | 468
Ahoj, diky za myšlenku, tohle znám. Když si sahnu takto na komponentu, tak pořád nedojde k jejímu rendereru. Data mam k dispozici skutecne až v render metode, protože tam mám k dispozici config, který se mění, takže žádný handle ani monitor v constructoru, protože tam není znám ten config viz nahoře, getCurrentConfig. Jinak uz je to na prvni pohled takové vousate a nelogické, nicméně se v tom pro zajimavost/self-learn porypu. 3/ řešení je naprosto logicke, jasne a s minimem prace.
- Martk
- Člen | 661
Ke 4, když už chci sahat na data komponenty, tak už je v hlavě
vykřičník, že je něco asi špatně a nakonec přijdu, že ano. Když chci
data až v render metodě, tak to už vím 100%, že je něco špatně. Podle
kódu $config = $this->getCurrentConfig($config);
vidím, že ty
data můžeš mít k dispozici kdykoliv. Stačí kód přepsat do
$this->getCurrentConfig($this->getParameter('config'));
a
můžeš je mít v createComponent nebo startup metodě.
- Kcko
- Člen | 468
Martk napsal(a):
Ke 4, když už chci sahat na data komponenty, tak už je v hlavě vykřičník, že je něco asi špatně a nakonec přijdu, že ano. Když chci data až v render metodě, tak to už vím 100%, že je něco špatně. Podle kódu
$config = $this->getCurrentConfig($config);
vidím, že ty data můžeš mít k dispozici kdykoliv. Stačí kód přepsat do$this->getCurrentConfig($this->getParameter('config'));
a můžeš je mít v createComponent nebo startup metodě.
Jasně, není to ideální, ideální je v tomto případě 3). Jenom tady nechápu, kde a jak a proč si mám posílat GETem config?
Komponenta funguje takto:
- má defaultní config přímo v sobě
- můžu komponentu nastavit skrz DB (je takové magické, abych nemusel vytvářet komponenty přes továrnu v presenteru), pak se config v případě potřeby mergne (přepíše nebo to co je jiné než výchozí)
- mohu pak v presenteru (akcích / renderech ..) komponentu nasetovat a doupravit finálně její config; což dělám dost často (vytáhnu řádek z DB a nějakým způsobem upravím config komponenty na základě získaných dat, to ve startupu nezjistím).
Nechápu tedy tu poznámku o nastavení skrze startup v presenteru ;), pokud jsi to myslel jinak, než jsem pochopil, prosím o demo ukázku, jinak považujme za vyřešené, řešení 3 je fajn a vyhovující a v noci včera mě nenepadlo ;-)
- Martk
- Člen | 661
Podle kódu v prvním postu vidím, že na základě parametru config si získáváš aktuální config.
Všechno co se týče db, defaultní hodnoty, nastavování, merge, doupravování configu by nemělo být v komponentě ani presenteru, ale uděláš si na to samostatnou třídu.
Továrny na komponenty jsem taky moc nedělával, byl jsem líný, ale zjistil jsem, že už jsem musel kód tolikrát přepisovat na továrnu, že už to dělám automaticky a nic mě to nestojí.
Pokud ti stačí 3, tak ok. Jenom jsem doplnil odpověď, třeba se bude hodit do budoucna.
- Kcko
- Člen | 468
Martk napsal(a):
Podle kódu v prvním postu vidím, že na základě parametru config si získáváš aktuální config.
Všechno co se týče db, defaultní hodnoty, nastavování, merge, doupravování configu by nemělo být v komponentě ani presenteru, ale uděláš si na to samostatnou třídu.
Továrny na komponenty jsem taky moc nedělával, byl jsem líný, ale zjistil jsem, že už jsem musel kód tolikrát přepisovat na továrnu, že už to dělám automaticky a nic mě to nestojí.
Pokud ti stačí 3, tak ok. Jenom jsem doplnil odpověď, třeba se bude hodit do budoucna.
Díky, v budoucnu se nad tím ještě zamyslím, kvůli lepší flexibilitě-