Po půl roce znovu otevírám otázku zjednodušení
životního cyklu presenteru, tentokrát v nových reáliích:
továřnička na komponenty už je standardní a zaběhlou součástí
frameworku, některé nové vlastnosti frameworku na ní budou záviset.
Můj návrh zní:
zrušit metody beforePrepare() a
prepare<View>()
zrušit metodu afterRender() (její název je velmi
zavádějící)
Se vším souhlas.
Zavádějící – protože renderování probíhá až po ní? :o)
BTW, Davide, nechceš sepsat povídání o nových šablonách, když jsi je
z gruntu přepsal? :) Bývala by mi stačila přednáška z PS, ale Tomik ji
zveřejní až v srpnu :(
Souhlasím s obojím, s příchodem továrničky přestaly mít valnější
smysl. A se supertovárničkou
a {widget} „skoro“ můžou zmizet i
render<Action>() ;-)
Kde je nějaké povídání, co {widget} dělá?
Nóóó… ve zdrojáku??? :-) Zatím asi nikde nic není. Ale je to
jednoduché: {control grid:paginator} vloží něco jako
$presenter->getComponent('grid')->renderPaginator();.
David Grudl napsal(a):
Překvapilo mě, jaké souznění zaznělo nad tím, že se něco
zruší ;)
Mě taky ;-)
Totiž říkám si, že by se tam mohlo objevit třeba
beforeHandle().
Jestli to správně chápu, beforeHandle() by vlastně bylo
místo beforePrepare().
Zde by se zřejmě tedy mohla řešit nějaká customizace obsluhy signálů?
Zdá se to logické, ale já jsem zatím podobnou funknčnost nepotřeboval.
Teoreticky ano, spíš mi šlo o to, jestli to tak používáš skutečně.
Totiž říkám si, že by se tam mohlo objevit třeba
beforeHandle().
beforeHandle parádně řeší problém ze signálama.
Nejčastěji se to stejně používá pro nějaké globální signály (pro
všechny view) nebo si to snadno omezím jen pro nějaký
if ($this->getView() == 'nejaky') případně si vždycky můžu
původní chování simulovat
$this->tryCall('prepare'.$this->getView(), $this->params);.
A název beforeHandle je mnohem srozumitelnější kdy se volá, takže
jednoznačně palec nahoru ;], tedy jestli se ještě někdo neozve že to
používá k něčemu jinému. Jak vlastně plánuješ to odstranit? Prostě to
na to dáš trow new DeprecatedException, nebo to rovnou smažeš
(přeci jen je to vývojová verze), nebo budeš nějak složitě řešit bc
(a jak)?
Jen mě teď napadá – jde provést redirect v renderXYZ()?
Jedná se mi o situaci, kdy na základě nějaké vnitřní hodnoty
rozhodujete, že dané view bude přesměrováno.
Ten afterRender() se mi líbil na volání funkcí, které musí jít až po
renderu, ty funkce, které se musejí volat v každém pohledu – například
generátor title, keywords, apod. Teď je budu muset volat v každém
renderXYZ() na konci.
No ikdyz budu jedinej co to sem napise (asi), ja bych prepareXyz() nerusil.
Zvyk jsem si pripravovat data pro editacni formular prave v prepareEdit() a
v renderEdit() mam pouze a jen prirazeni hodnot do sablony.. Prijde mi to
prehlednejsi pro lazeni. To mi budete radit, abych tyhle faze (priprava dat pro
editacni formular) provadel v renderXyz() popr. v actionXyz()?
Jen mě teď napadá – jde provést redirect v renderXYZ()?
Jedná se mi o situaci, kdy na základě nějaké vnitřní hodnoty
rozhodujete, že dané view bude přesměrováno.
Ten afterRender() se mi líbil na volání funkcí, které musí jít až po
renderu, ty funkce, které se musejí volat v každém pohledu – například
generátor title, keywords, apod. Teď je budu muset volat v každém
renderXYZ() na konci.
Me se taky hodil afterRender… pokud jsem chtel sablonu odeslat jako snippet
tak jsem to zaridil prave v afterRender:
<?php
abstract class ServicePresenter extends BasePresenter
{
private $targetSnippet = NULL;
public function getTargetSnippet()
{
return $this->targetSnippet ? $this->targetSnippet : FALSE;
}
public function renderTemplateToSnippet($name)
{
$this->targetSnippet = $name;
}
protected function afterRender()
{
if ($targetSnippet = $this->getTargetSnippet())
{
if (!$this->isAjax()) throw new NBadRequestException("This view responses on ajax request only.");
$this->template->setFile($this->getTemplateFile());
$this->payload->snippets[$targetSnippet] = (string) $this->template;
$this->terminate();
}
parent::afterRender();
}
}
?>
Pak mi stacilo v u potomku zavolat $this->renderTemplateToSnippet($name)
a sablona se mi vyrenderovala do snipetu…
Já bych prepare určitě zrušil. Pak to začátečníci používají a
komplikuje jim to život. Žádné výhody prepare nevidím.
Jinak názvy metod beforeRender a afterRender jsou opravdu nešťastné.
Představoval bych si pod těma názvama, že nejdřív bude render<View>,
pak beforeRender, pak vykreslení šablon a potom afterRender.
Jinak afterRender jsem použil, ale smysl toho použití mizí s novýma
šablonama.
Jen mě teď napadá – jde provést redirect v renderXYZ()?
Jedná se mi o situaci, kdy na základě nějaké vnitřní hodnoty
rozhodujete, že dané view bude přesměrováno.
Dokud se něco nevypíše na výstup, jde volat redirect.
Ten afterRender() se mi líbil na volání funkcí, které musí jít až po
renderu, ty funkce, které se musejí volat v každém pohledu – například
generátor title, keywords, apod. Teď je budu muset volat v každém
renderXYZ() na konci.
Zjednodušování se mi líbí, sám jsem měl problémy se vyznat v tom, co
dát do jaké metody. A že jich bylo požehnaně. Navíc továrničky
přinášejí mnohem elegantnější a ucelenější způsob práce
s komponentami a bude jen dobře, pokud framework bude tuto cestu
podporovat.
sodae napsal(a):
jak píše washo tak přesně tohle opravdu teď potřebuji
takže afterRender bych nerušil určitě
A není nějaký jednoduchý způsob jak tuhle metodu nahradit?
A není nějaký jednoduchý způsob jak tuhle metodu nahradit?
Jedině že by david přidal události a ty by sis pak zvolil co se má volat
$presenter->onAfterRender[] = array($presenter,'afterRender',$presenter->params);
Nicméně to je pak skoro stejný jako jí tam nechat (a třeba jen
přejmenovat)
zrušit metodu afterRender() (její název je velmi
zavádějící)
Co myslíte? Jsou případy, kdy to nejde?
A jaky vlastne by mel byt duvod zruseni? Osobne si myslim, ze bud to nekdo
vyuziva a pak to oceni a nebo to nekdo nevyuziva a muze mu to byt skoro jedno,
ze se takove metody daji psat ne? Takhle mi prijde, ze clovek muze zasahnout do
zpracovavani pozadavku na ruznych mistech podle toho, co potrebuje udelat (a
nebudu si tu ted vymyslet konkretni veci, protoze vsichni vime, ze se na to
vzdycky prijde primo pri vyvoji) a likvidovat tuhle moznost je skoda ne?
Jelikož prepare metody jsou historickým reliktem a jak si sám můžeš
v citovaném příspěvku přečíst, tak název metody afterRender je velmi
zavádějící :-D
afterRender bych ponechal a ani nevidím důvod, proč měnit název –
chápu, že nedochází k renderování před provedením afterRender(), ale
pokud se jmenují metody renderXYZ(), tak pak mě logicky napadá, že
afterRender() je naprosto v pořádku. Přejmenování bych viděl jako
řešení zbytečné zpětné nekompatibility a neřeší to nic… to
můj názor.
Já jsem pro, afterRender() jsem snad nikdy nepoužil a prepare
metody od doby továrničky už také nepoužívám.
Taky tak. Jen bych se zastavil nad názvem metody beforeHandle a
jejím významem (příjde mi trošku zavádějící) – podle obrázku co tu
je výše se tato metoda volá při každém požadavku nebo jen při
zpracování signálu?
s pomocí widgetů už skoro není třeba metoda render;-)…
A mám jeden nápad/feature request…
Když už nette parsuje anotace… napadá mě:
K čemu potřebuju render metodu – k widgetům ne, ty se bez ní
obejdou. A pokud v ní předávám něco jiného, pak to něco jiného mám
obvykle jako property presenteru.
Tudíž mě napadá, zda by nebyla WAY udělat novou anotaci, třeba něco
jako @rendered, a Presenter by v beforeRenderu prošel svoji reflexi a
všechen property co má anotaci @rendered by hodil do templaty jako
stejnoměnou proměnou templaty – bylo by to vlastně takové auto
assignování templetám…
Není to škoda? Pokud jen potřebuju zobrazit šablonu kterou naplním daty
z modelu, tak se krásně hodí render, kde mám pouze něco jako
$this->template->foo = $this->model->getBars();
Je docela zbytečné to ládovat jako property presenteru a ještě to
anotovat (nebo vytvářet Control o ničem a ten pak widgetovat), takhle mi to
přijde přehlednější. Nebo ne?