V componentě generuju form a někde se mi ztrácí parametr
- Flipajs
- Člen | 29
Components.php
UsermainPresenter.php
default.phtml
Problém je někde na těchto řádcích.
Jde o to, že po odeslání formuláře (který se vykreslí v pořádku nedojde k odeslání čehokoliv co bylo vytvořeno pomocí proměnné $rIds… Tedy zřejmě ten parametr posílám někde ve špatný čas.
Procházel jsem fóra křížem krážem, ale už z toho mám velkou hlavu a kdyby to šlo hrubou silou (kladivem atd.) tak už jsem to tak dávno udělal =D
Díky za jakoukoliv radu. Vycházel jsem z tohoto příspěvku
- westrem
- Člen | 398
Problem je jasny.
Tento riadok:
{control requestsForm, 'adminCompetitionRequests'.$myCompetition['id'], $myCompetition['requests']}
tam sice predavas parametre lenze tu:
protected function createComponentRequestsForm($name)
{
return new AdminCompetitionsRequests();
}
ich nikde nevyuzivas a teda sa v danej classe
AdminCompetitionsRequests
nikdy nenastavi to
$rIds
.
- Flipajs
- Člen | 29
Dobřé, ale jak to mám tedy udělat? Pokud zadám:
protected function createComponentRequestsForm($name, $rIds)
{
return new AdminCompetitionsRequests($name, $rIds);
}
dostanu Warning: Missing argument 2 for UsermainPresenter::createComponentRequestsForm(), called in…
Pokud někdo může, ukažte prosím jakým způsobem předávat z template ten parametr přes továrnu komponentě.
Díky!
Editoval Flipajs (19. 12. 2010 13:04)
- Flipajs
- Člen | 29
Reagoval jsem na westerna…
V componentě to dělám tak jak podle mě popisuješ, tedy:
public function render($name, $rIds)
{
$this->rIds = $rIds;
$this->getComponent('form')->render();
}
/** @var array */
public $rIds;
Dokonce i když si v createComponentForm dumpnu $this->rIds tak v něm
je to co má být.
V formu provádím: $form->addRadioList(‚request_ida‘.$i,
$this->rIds[0][‚login‘], $requestRadio);
Po odeslání formu jako by se vůbec $this->rIds nepředalo. Form se odešle se vším všudy, ale kde bylo použito $rIds tak je problém a vážně nevím co s tím :-/
Editoval Flipajs (19. 12. 2010 13:04)
- westrem
- Člen | 398
Ach .. vidim, ze bude treba obsirnejsie vysvetlit ..
Za prve mas tam cudne carovanie s tym $rIds
:
// este OK
public function render($name, $rIds)
{
$this->rIds = $rIds;
$this->getComponent('form')->render();
}
// ..
// tu je ten parameter druhy zbytocny, pretoze sa nedosadzuje
protected function createComponentForm($name, $rIds)
{
$requestRadio = array('confirmed' => 'confirm', 'waiting' => 'wait', 'declined' => 'decline');
$this->rIds = $rIds; // Zbytocne
$this->rIds = (array)$this->rIds; // pretypovanie mozes riesit uz v tej metode predtym
$form = new AppForm();
Debug::dump($this->rIds);
$form->addText("test", "Test");
$i = $this->rIds[0]['login'];
$form->addRadioList('request_ida'.$i, $this->rIds[0]['login'], $requestRadio);
$form->addHidden('test2')->setValue($this->rIds);
$form->addSubmit('odeslat', 'Odeslat');
$form->onSubmit[] = array($this, 'requestListSubmitted');
return $form;
}
Tvoj hlavny problem je ale uplna tradicna zalezitost .. ty tie parametre
generujes az v render fazi a predavas ich formularu len potom, to znamena, ze
pri vykonani public function requestListSubmitted(AppForm $form)
sa
ti zakonite nevygeneruje tebou pozadovany formular.
Upravil by som to teda tak, ze by som si potrebne parametry generoval v
actionDefault
v presenteri, ulozil do premennej presenteru a pri
volani createComponentRequestsForm
kde vytvaras tu komponentu, ich
tam nastavil.
Dufam, ze uz je to jasnejsie ;)
- westrem
- Člen | 398
O zivotnom cykle presenteru a to ake metody sa kedy volaju sa docitas v prislusnej dokumentacii. Control ma tiez svoju dokumentaciu
- Flipajs
- Člen | 29
Upravil by som to teda tak, ze by som si potrebne parametry generoval v actionDefault v presenteri, ulozil do premennej presenteru a pri volani createComponentRequestsForm kde vytvaras tu komponentu, ich tam nastavil.
No není mi pořád ještě jasné jak v createComponentRequestsForm poznám které hodnoty mám přiřadit (Těch formů se genreuje více)…
Jsem z toho jelen :-/ :-x
Editoval Flipajs (19. 12. 2010 15:12)
- Filip Procházka
- Moderator | 4668
asi jsem to možná nečetl ani celé, ale mohla by pomoct malá nápověda: i v komponentě můžou být persistentní parametry ;)
- Flipajs
- Člen | 29
Z toho co jsem četl v jiných problémech a bylo mi řečeno tady jde o to, že předávám ty parametry až v renderu což už je pozdě tedy po kliknutí na odeslat jako by neexistovaly a na to nevím jestli by persistentní parametr pomohl. Stejně by se nic nepřeneslo, protože by s tím ten form ještě nepočítal, ne?
Potřebuju vědět jak provést toto:
„Upravil by som to teda tak, ze by som si potrebne parametry generoval
v actionDefault v presenteri, ulozil do premennej presenteru a pri volani
createComponentRequestsForm kde vytvaras tu komponentu, ich tam nastavil.“
jak zjistit který form se zrovna v tempalte vytváří a získat si někde z té proměnné presenteru ty hodnoty a ty nastavit té komponentě?
- Filip Procházka
- Moderator | 4668
pokud to zapíšeš pomocí $presenter->parametr = 5
tak by
persistence mohla pomoct, zkus :)
- Flipajs
- Člen | 29
Netuším jak je to myšleno… Jak se z té componenty potom dostanu na ten původní presenter a jak budu vědět čím to mám naplnit?
v templates
{control requestsForm, 'adminCompetitionRequests'.$myCompetition['id'], $myCompetition['requests']}
potřebuju prostě ten parametr co tam posílám dostat ještě před renderováním do té componenty a na základě toho vytvořit formulář. Jak bylo navrženo naládovat to někde v presenteru v ActionDefault do nějaké proměnné… Na tom nerozumím tomu, jak pak v továrničce zjistím který formulář to zrovna je? (protože tam mi nechodí ještě žádný parametr)…
- Filip Procházka
- Moderator | 4668
v první řadě takový menší detail
{control requestsForm, 'adminCompetitionRequests'.$myCompetition['id'], $myCompetition['requests']}
je docela zbytečné…
říkal jsem si, že by ti mohlo vyhovovat něco takového:
{control requestsForm, $myCompetition}
komponenta:
class RequestsForm extends Nette\Application\Control
{
/** @persistent */
public $rId;
protected function attached($presenter)
{
// vytvoříme formulář, aby mohl příjmout signál
// z principu stačí vytvořit ve výchozím stavu pouze jeden formulář,
// protože nette dovoluje zpracovat pouze jeden signál v jednom requestu
$this->createAndAttach($this->rId)
// o zbytek se postará životní cyklus
parent::attached($presenter);
}
// pro renderování hromady formulářů pro každý competition zvlášť
public function render($competition)
{
$form = $this->createAndAttach($competition['id']);
$form->render();
}
protected getReceiverFormName($id)
{
return 'adminCompetitionRequests'. $id;
}
protected function createAndAttach($id)
{
$name = $this->getReceiverFormName($id);
$this[$name] = $this->createForm($id);
// tady je trošku magie, možná to bude chtít poladit, aby to generovalo správný tvar
$fullname = $this->lookupPath(get_class($this));
$this[$name]->action->setParam($fullname . self::NAME_SEPARATOR . 'rId', $id);
return $this[$name];
}
protected function createForm($rId)
{
$requestRadio = array('confirmed' => 'confirm', 'waiting' => 'wait', 'declined' => 'decline');
$form = new Nette\Application\AppForm();
// nevím jak ten formulář má přesně fungovat, ale něco takového by mohlo být asi jak jsi to myslel
$form->addText("test", "Test");
$form->addRadioList('request_ida', $rId, $requestRadio);
$form->addHidden('rId')->setValue($rId);
$form->addSubmit('odeslat', 'Odeslat');
$form->onSubmit[] = array($this, 'requestListSubmitted');
return $form;
}
public function requestListSubmitted(Nette\Application\AppForm $form)
{
dump($form->getValues());
}
}
presenter:
protected function createComponentRequestsForm($name)
{
return $form = new RequestsForm($this, $name);
}
Když o tom tak přemýšlím, tak jestli tohle funguje, tak je to vlastně univerzální řešení pro více stejných formulářů na stránce :)
Editoval HosipLan (19. 12. 2010 18:21)
- Flipajs
- Člen | 29
Tak jsem to vyzkoušel.
Hlásí mi to toto:
InvalidStateException
Component ‚requestsForm‘ is not attached to ‚RequestsForm‘.
Napadlo mě (ale asi je to blbost :-x) v presenteru udělat v cyklu něco
jako
$requests = new RequestsForm($this,
‚adminCompetitionRequests‘.$myCompetitions[$i][‚id‘]);
Pak se objeví toto:
InvalidStateException
Component ‚adminCompetitionRequests17‘ is not attached to ‚RequestsForm‘.
Ještě nějaký nápad kde by mohla být chyba? Co s tím? Díky!
- Flipajs
- Člen | 29
Tak nakonec jsem to vyřešil takto:
public function actionDefault()
{
//nějaké získání $myCompetitions...
for($i = 0; $i < count($myCompetitions); $i++)
{
$request = new AdminCompetitionsRequests;
$request->setValues((array)$myCompetitions[$i]);
$this['adminCompetitionRequests'.$myCompetitions[$i]['id']] = $request;
}
}
V componentě:
public function setValues($rIds)
{
$this->rIds = (array)$rIds; //prostě předání nějakých těch parametrů co potřebuju pro vytvoření formu
}
A nakonec templates:
probíhá v foreach...
{control "adminCompetitionRequests".$myCompetition['id']}
Zatím se zdá, že to funguje. Děkuju všem za pomoc. Snad tohle pomůže do budoucna nějaké podobné lamě jako jsem já. (I když nevím jestli je to úplně čistý řešení)…
Editoval Flipajs (20. 12. 2010 22:57)
- Filip Procházka
- Moderator | 4668
Ach kdy se naučíte používat foreach :)
public function actionDefault()
{
//nějaké získání $myCompetitions...
// for($i = 0; $i < count($myCompetitions); $i++)
foreach ($myCompetitions as $competition)
{
$request = new AdminCompetitionsRequests;
// $request->setValues((array)$$myCompetitions[$i]);
$request->setValues((array)$competition);
// $this['adminCompetitionRequests'.$myCompetitions[$i]['id']] = $request;
$this['adminCompetitionRequests'.$competition['id']] = $request;
}
// žádná kouzla s ID, pouze komponenty, které opravdu chci
$this->template->competitions = $this->getComponents(FALSE, 'AdminCompetitionsRequests');
}
{foreach $competitions as $component}
{control $component}
{/foreach}
To moje je sice o několik řádů víc magické, ale příjde mi to mnohem víc efektivnější :)
Editoval HosipLan (21. 12. 2010 0:34)