Action vs. View, QS, konvence?
- Endrju
- Člen | 147
Zdravim :)!
Par mesicu se uz prokousavam Nette a dnes jsem si vsiml jedne zvlastnosti. Prochazel jsem znova QuickStart, ktery prosel nejakymi zmenami.
V casti Vytvoreni presenteru se hovori o tom, ze kazda akce by mela mit 2 metody:
final class TodolistPresenterPresenter extends BasePresenter
{
public function actionShow()
{
}
public function renderShow()
{
}
}
Tedy v metode action*() by se melo pracovat s modelem a v metode render*() pak se sablonou pohledu. To je v podstate nastineno take v dokumantaci Action vs. View.
Pak jsem si ale vsiml, ze presentery presentery v prikladu CD-collection
z distribuce jsou napsany v rozporu s predchozim. Zde napriklad v presenteru
Dashboard v metodach renderDefault()
,
renderEdit($id = 0)
a renderDelete($id = 0)
pracujeme
s modelem (vytvoreni instance modelu a predani dat pohledu) i presto, ze podle
toho, co je psano v QS by prace s modelem mela probihat v metodach
action*()
. Ovsem jaky by pak byl obsah metod
render*()
? Pravdepodobne zadny?
Z toho co jsem doposud pochytil je v podstate „jedno“ (pokud se nebudeme drzet konvenci), zda to napiseme do render*() nebo action*() metody. Fungovat to bude stejne. Dle meho laidskeho usudku se v prikladu CD-collection pracuje s modelem v metode render*() z ciste jednoducheho duvodu. Pokud by se tento kod presunul do metod action*(), tak by pak obsah metod render*() byl prazdny. Je to tak ciste z tohoto duvodu nebo se mylim?
Pro novacka to muze byt docela matouci. Po precteni QS si projde obsah distribucniho baliku a urcite ho budou zajimat priklady v adresari examples. Tam najednou zjisti, ze se s modelem pracuje v metodach render a ne action, jak se docetl v QS a bude zmateny..
Z tohoto tedy vyplyvaji dva zavery:
- Bud jsou informace v QS nepresne (zavadejici)
- nebo je priklad CD-collection nekorektne napsan a mel by byt dopnene minimalne o nejaky komentar.
Mohli by jste nekdo kompetentni (Davide?) rozlustit tuhle „zahadu“ kolem konveci? Co vse je mozne psat do metod action*() a co do metod render*()?
Dale me zajima: je mozne (ci se nedoporucuje) pracovat s modelem v tovarnickach na formulare?
Priklad: ve formulari potrebuju mit selectBox, ktery potrebuju naplnit daty z databaze. Je v tomto pripade nejaky vhodnejsi postup, nez vytvoreni instance modelu v tovarnicce formulare, kde provedeme zaroven naplneni selectBoxu daty, ktere nam dodal model?
Pro uplnou predstavu napriklad takto:
protected function createComponentRegisterForm()
{
$form = new AppForm;
$citiesModel = new CitiesModel;
$cities_list = $citiesModel->findAll()->orderBy('nazev', dibi::ASC)->fetchPairs('id_mesta', 'nazev');
$form->addText('jmeno', 'Jméno:')
->addRule(Form::FILLED, 'Vyplňte jméno prosím.');
$form->addText('prijmeni', 'Příjmení:')
->addRule(Form::FILLED, 'Vyplňte příjmení prosím.');
$form->addSelect('id_mesta', 'Město:', $cities_list)
->skipFirst('Vyberte město')
->addRule(Form::FILLED, 'Vyberte město prosím.');
$form->addSubmit('save', 'Registrovat');
$form->addSubmit('cancel', 'Zrušit')
->setValidationScope(NULL);
$form->onSubmit[] = callback($this, 'registerFormSubmitted');
$form->addProtection('Odešlete formulář znovu prosím (bezpečtnostní token vypršel).');
return $form;
}
Dekuji moc za osvetleni teto problematiky.
Editoval Endrju (8. 4. 2010 0:43)
- Honza Marek
- Člen | 1664
Metody action i render jsou nepovinné, můžeš je vynechat jak je libo. Co dát do které, to není pořádně jasné ani mě, i když s nette dělám už dlouho. V praxi je mezi těma metodama ten rozdíl, že action proběhne před zpracováním signálů (např. odeslání formuláře) a render po. Pokud signály s logikou kódu nezamíchají, je myslím prakticky jedno, do které z metod to napíšeš.
Ad model v továrničkách: Já bych to doporučoval ;-)
Editoval Honza Marek (8. 4. 2010 1:53)
- Jiří Šafra
- Člen | 3
Přesně tohle by mě také docela zajímalo, co patří do action() a co do
render().
Také jsem v Nette začátečník a zatím k tomu přistupuji tak, že cokoli
mi může ovlivnit jak (a jestli vůbec) se mi něco vykreslí, dám do
action(), ostatní do render(). Takže třeba kontrolu práv a případné
přesměrování na přihlašovací formulář řeším v action(), ale
načtení dat z modelu už v render().
Možná to tak není správně, pokud někdo zkušenější řekne, jak by to
mělo být, tak budu jedině rád.
- Honza Marek
- Člen | 1664
Jiří Šafra napsal(a):
Řekl bych, že to děláš dobře. Ono se nedá striktně říct, tohle musí být v action a tamto v render, protože je to často úplně jedno.
Editoval Honza Marek (8. 4. 2010 11:53)
- Ondřej Mirtes
- Člen | 1536
Do action patří málo co, dával bych tam např. dodatečné settery komponent, které závisí na parametru akce, nebo třeba setDefaults formuláře. Patří tam taky rozhodovací logika $this->setView(), která je vidět např. ve Skeletonu v ErrorPresenteru.
Do render bych dal všechno plnění šablony (a nikam jinam). Pokud totiž dáte plnění šablony do action a signál vám s těmi hodnotami něco provede, tak budete mít v šabloně staré hodnoty (pokud neděláte redirect, např. při AJAXu).
Pokud nemáte v Presenteru žádný takový signál, tak plnění šablony v action nic nebrání, ale proč nedodržovat jednotnou konvenci, že. „Investice“ do ní se vám vrátí :)
- JakubKohout
- Člen | 92
Já osobně se snažim všehno strkat do render, a do action jen ty potřebné věci před handle. Například do action nastavení privátních atributů presenteru v závislosti na vstupních parametrech.A pokuud není možné dát rozhodovací info o právech do startupu tak to cpu do action
- Ondřej Brejla
- Člen | 746
Tak třeba…
jakási logika → action
plnění šablony (ať už z modelu nebo buh ví odkud) → render
Editoval Ondřej Brejla (8. 4. 2010 17:01)
- Honza Kuchař
- Člen | 1662
Od té doby co se používají továrničky, už se používají metody render*() minimálně.
- Honza Marek
- Člen | 1664
honzakuchar napsal(a):
Od té doby co se používají továrničky, už se používají metody render*() minimálně.
A $this->template->article = Model::getArticleData($id)
apod vyrábíš v action metodách?
- Honza Kuchař
- Člen | 1662
Ne. Když třeba zobrazuji článek, tak data předávám šabloně v render metodě. Ale na všelijaká meníčka a podobné používám komponenty.