manevrovanie medzi action{Action} a render{view}
- edke
- Člen | 198
Mam {action}
, kde kombinujem prehlad zaznamov tabulky a
formular. Ako mi to doteraz vychadza:
- Formular musi byt v
action{Action}
, pretoze signal je spracovany poaction{Action}
a v tom momente ak neexistuje objectAppForm
,processSignal()
nevie ako nalozit so spracovavanym signalom. Pravda ? - Ak
{action}
potrebuje reagovat na signaly, musi byt umiestneny vrender{view}
. Ak by bol umiestneny vaction{Action}
, signal bude spracovany az po vygenerovani{view}
a ten ak sa meni vdaka tomuto signalu, ta zmena sa prejavi az po dalsom kliku, co je hlupost samozrejme. Pravda ?
Tak a teraz spat k mojmu problemu. Pre lepsiu nazornost sshot. Strankovanie, sortovanie, to su vsetko {signaly}!.
Buttony su SubmitButton
vo formulari. Kazdy riadok ma checkbox, pre
multiple operacie, ako napriklad mazanie viacerych zaznamov.
Ten problem spociva prave v tom, ze v tom {view}
kombinujem
formular, ktory by mal byt v action{Action}
s dalsou castou, ktora
by mala byt v render{view}
. A nemozem to ani rozdelit, teda
formular do action{Action}
a zbytok do render{view}
,
pretoze checkboxy viem vygenerovat az ked mam spocitane strankovanie, spracovane
{signaly}!
, teda v render{view}
. A ak ich
k formularu pripojim az v render{view}
, po odoslani formulara
buttonom nie je v ->getValues()
samozrejme.
Co vcul ?
- edke
- Člen | 198
edke wrote:
Co vcul ?
Dumal som a nasiel som 2 riesenia a ani jedno sa mi nepaci :)
1. riesenie
protected $form;
public function actionDefault() {
$form = new AppForm($this, 'main_table');
$form->addSubmit('add', 'Pridať záznam' )
->onClick[] = array( $this, 'default_onAdd');
$form->addSubmit('delete', 'Zmazať záznam' )
->onClick[] = array( $this, 'default_onDelete');
$this->form=$form;
}
public function renderDefault() {
$form= $this->form;
...
foreach( $res as $row ) {
$_loop= array();
$control= $form->addCheckbox( $row['id'], null );
$_loop[]= array( 'align' => 'center', 'content' => $control->control );
...
Cast form mame v action aj so submitmi a zadefinovanymi signalmi. Cast tabulka mame v render, teda signaly! v <a href> na order a na zmenu strany budu fungovat tiez korektne.
Jediny problem je so submitmi add, delete:
public function default_onEdit( SubmitButton $button )
{
$values= $button->getForm()->getValues();
var_dump( $_POST );
var_dump( $values );
Oznacene checkboxy vo $values samozrejme nebudu, pretoze neboli definovane v action, ale az v render. Ale obidem to tak, ze si ich vyberiem priamo z $_POST.
Samozrejme riesenie je „prasarna“, zrusil som velku vyhodu Nette\Forms a to ze nespracuje ziadne hodnoty, pokial neboli predtym definovane v aplikacii. Podstrcenie hodnot musim osetrit sam. Ale hlavne to je nesystemove riesenie.
2. riesenie
Vsetko, aj tabulku aj formular presuniem do actionDefault
.
Submitovanie z formulara je uplne v poriadku, cely objekt AppForm je
definovany v action. Problem je so signalmi! order a page. Tie uz nebudu
fungovat. Tak ich prerobim na view:
public function actionPage( $page )
{
$page= (int) $page;
if ( !( $page > 0) ) {
throw new Exception('page is not valid');
}
$namespace= Environment::getSession($this->tableName);
$namespace->page= $page;
$this->redirect( 'default');
}
Co sa mi zas na tomto rieseni nepaci je, ze pouzivam view ako handler, musim pouzit redirect, takze kvoli „signalu“ musim aplikaciu volat 2×.
- romansklenar
- Člen | 655
LM napsal(a):
Pokud ty view nebudou používat stejný parametry, pak nevidím důvod, proč je mít v jednom presenteru. Nebo bych zvážil z toho udělat komponentu…
Možná pomůže: Návrh struktury presenters/views
- edke
- Člen | 198
romansklenar wrote:
Možná pomůže: Návrh struktury presenters/views
Toto mam precitane, myslim, ze ta struktura je navrhnuta dobre. Jeden presenter je sprava jednej tabulky.
- view default – zobrazuje tabulku zaznamov a umoznuje :
- sortovanie zaznamov
- strankovanie zaznamov
- nastavovanie filtrov
- zmena view na formular
- view form – zobrazuje formular, ktory umoznuje pridavat/updavovat/editovat zaznamy.
Zaujimal by ma Davidov nazor, ci by vedel poradit nejake cistejsie systemove riesenie.
- David Grudl
- Nette Core | 8218
Ty potřebuješ, aby pořadí úkolů bylo:
- inicializace presenteru (včetně např. připojení k db, …)
- provedení signálů „Strankovanie, sortovanie“
- vytvoření formuláře
- provedení signálů pro formulář
- vykreslení stránky
To je zcela legitimní požadavek. Takže jak na to…
Životní cyklus presenteru je rozdělen do několika částí
představovaných voláním volitelně existujících metod. Jde o
action{Action}
, handle{Signal}
a
render{View}
.
Platí tu určitá pravidla: v okamžiku volání render{view}
už nemá docházet k žádným změnám parametrů, „vnitřní stav“ je
konečný. Protipólem je action{action}
, kde je prostor pro
manipulaci s modelem s možností následného přesměrování.
Tudíž v kterékoliv fázi předcházející handle{signal}
můžeme vykonat signál manuálně zavoláním metody
$this->processSignal()
. Příklad:
if ($this->isSignalReceiver($this, 'strankovanie') || $this->isSignalReceiver($this, 'sortovanie')) {
$this->processSignal();
}
Tím je signál provedený a už se nebude znovu volat.
Metoda isSignalReceiver()
ověří, zda je komponenta (první
argument) příjemcem signálu (druhý argument). Druhý argument můžeme
vynechat – pak zjišťuje, jestli je komponenta příjemcem jakéhokoliv
signálu. Experimentálně lze jako druhý parametr uvést TRUE a tím ověřit,
jestli je příjemcem nejen uvedená komponenta, ale také kterýkoliv její
potomek.
ps: zjednodušil jsem ověřování příjemce, takže isSignalReceiver vyžaduje poslední revizi Nette