Action vs. View, QS, konvence?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Endrju
Člen | 147
+
0
-

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
+
0
-

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
+
0
-

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.

despiq
Člen | 320
+
0
-

z myho hlediska jde o pred a po signalech
a action chapu jako provadeni zmen
a render jako pripravovani sablony

a ze zacatku si myslim ze hledat v tom vyssi logiku nema vyznam, akorat te to bude zdrzovat

Honza Marek
Člen | 1664
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

Od té doby co se používají továrničky, už se používají metody render*() minimálně.

Honza Marek
Člen | 1664
+
0
-

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
+
0
-

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.

Ola
Člen | 385
+
0
-

Nevím, jak by to správně mělo být, ale vzhledem k tomu, že někde můžu potřebovat AJAXové mazání příp. upravování, dávám předávání dat do render metod, jinak by se změny neprojevily.

Ondřej Mirtes
Člen | 1536
+
0
-

Ola: Jojo, děláš to správně, kvůli tomu render metody jsou.