signál volá pouze defaultní render(): jak čistě vyrenderovat jen potřebný obsah?
- Prado
- Člen | 21
Zdravím,
můj problém:
Mám komponentu s několika renderXX() metodami lišícími se tím, kde je obsah vykreslován. Pokaždé jde víceméně o totéž, jinak formátované, případně selectované s jinými parametry.
Kvůli interaktivitě používám hojně signály a tady narážím na problém: Nette při nich vyvolá pouze metodu render() a já pak jako reakci na signál nemohu invalidovat jen potřebný snippet, protože ten touto metodou není vykreslen, ale je součástí šablon pro renderXX().
Existuje jakýkoliv způsob, jak toto ČISTĚ vyřešit?
Já dnes ručně z render() vyvolávám všechny ostatní renderXX() a to je na
nic (a poznámky s nadávkami na adresu Nette už mne neuspokojují :))
Používat deset samostatných komponent pro vykreslení 10× téměř
totožného rovněž nechci.
- mkoubik
- Člen | 728
Momochodem: mít v komponentě víc render metod není
úplně best practice. Radši bych si pro každé zobrazení vytvořil extra
šablonu (za předpokladu že se ty view liší jen formátováním), přidal si
setter $control->setViewName('viewName');
a všechno vykresloval
pomocí render()
(šablona
"MyControl.$this->viewName.latte"
). Případně si tu komponentu
poďeď pro každé view (pokud se ty view liší i zobrazovanými daty) a
název šablony si nastav do protected atributu.
A teď k tevému problému: signál by vůbec neměl volat
žádnou render metodu, asi něco děláš špatně. V handle metodě je
dobrým zvykem přesměrovat na stejné view
($this->redirect('this')
) pokud se nejedná o ajaxový
požadavek (v tom případě jen invaliduješ potřebné snippety).
Každopádně {control foo:bar}
by po překreslení mělo zavolat
správnou render metodu.
Radši ukaž kód té komponenty a šablony ze které ji vykresluješ.
Editoval mkoubik (13. 2. 2014 12:26)
- Felix
- Nette Core | 1247
Tohle jsem take resil. V metode render
ve ktere jsem nemel nic
jineho nez:
public function render()
{
if ($this->presenter->isAjax()) {
if ($this->isControlInvalid('basket-lite-status')) {
$this->renderLite();
}
if ($this->isControlInvalid('basket-list-order')) {
$this->renderListOrder();
}
}
}
- Prado
- Člen | 21
mkoubik:
No pojem „best practice“ má pro mne asi jiný význam. Mně naopak dává
maximální smysl nevytvářet deset komponent představující jiné pohledy na
totéž, ale právě mít jen jednu a v ní deset metod renderxx().
Obzvláště, když stejná komponenta může být na stránce vykreslena
vícekrát a pak není nutné duplikovat její vnitřní stavy (kolekce,
entity atd).
Postup s jednou render(), která se rozvětví mezi různé šablony také používám, ale jen tam, kde nasettovaný stav komponenty ovlivňuje výběr šablony pro vykreslení. Předat výběr view jako stav komponenty se mi nelíbí z pohledu čistoty a taková obezlička se projevuje právě i na nemožnosti vykreslit na stránce komponentu (instanci) vícekrát v jiné podobě.
V handle metodě právě při ajaxu není jasné jaké snippety se mají po invalidaci vykreslit.
Ukázku zdrojáku zaslal Felix, ta tento příklad dobře popisuje: dva různé pohledy na košík a třeba tam bude jeden handler pro odmazání položky z košíku, přičemž komponenta normálně netuší, který renderXX() má vykreslit.
Felix:
Díky tohle zkusím, já tam právě doteď volal zbytečně všechny renderery.
Takže pokud tohle bude fungovat i tam, kde se na stránce nepoužívají
všechny renderery, je můj problém vyřešen.
Editoval Prado (13. 2. 2014 22:40)