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.