Vlastni Presenter pro kazdou akci
- markoska
- Člen | 12
Zdravim,
mam presenter pro (vicemene) kazdou DB tabulku (EmailPresenter, PhonePresenter, PersonPresenter, …) a v nich akce renderDefault(), renderShow(), renderEdit(), …
Problem je, ze zakaznik si preje mit jeden veliky formular, kde zada nejenom udaje o osobe, ale i veskere jeji adresy, telefony, ucty, sluzby… Takze mi PersonPresenter zacal hrozive bobtnat
Vsiml jsem si, ze v dokumentaci radite vytvaret presentery s jedinou akci. To stejne radi i na itnetwork. Tak jsem si presenter rozsekal na PersonShowPresenter, PersonEditPresenter, …
Problem ale je, ze ted mam createComponentPersonForm() jak v PersonCreatePresenter tak v PersonEditPresenter
Napadlo me presunout formular do modelu Person, nevim ale, jestli tam vubec patri, zvlast kdyz obsahuje policka i jinych modelu.
Mate prosim nekdo toto vyresene?
Dekuji za nakopnuti spravnym smerem
Editoval markoska (2. 4. 2022 10:23)
- Marek Znojil
- Člen | 90
Zde máš popsány různé způsoby znovu použitelnosti formulářů:
https://doc.nette.org/…s/form-reuse
- markoska
- Člen | 12
Marek Znojil napsal(a):
Zde máš popsány různé způsoby znovu použitelnosti formulářů:
https://doc.nette.org/…s/form-reuse
Jeste bych se s dovolenim zeptal…
Vytvoril jsem si tedy tovarnu, presne podle toho navodu „form-reuse“, presunul do ni jak metodu, ktera formular vytvori, tak i metodu, ktera formular zpracuje.
V presenteru mi zustalo akorat:
protected function createComponentPersonForm(): Form
{
$form = $this->PersonFormFactory->create();
$form->onSuccess[] = function (Form $form) {
$this->redirect('this');
};
return $form;
}
Akorat, ze kdyz tu personu edituji, tak potrebuji nejak predat jeji ID. Predtim jsem mel v Presenteru toto:
public function personFormSucceeded(Form $form, \stdClass $values): void
{
$values->id = $this->getParameter('id');
try
{
$person = $this->Person->save($values);
....
Ted kdyz mam zpracovani formulare v tovarne, tak mi to samozrejme hlasi chybu:
Call to undefined method app\Modules\Is\Factory\PersonFormFactory::getParameter()
Jak si tam ted predam ID, ktere se mi vraci jako parametr z URL?
Dekuji
- markoska
- Člen | 12
Pepino napsal(a):
V actionDefault můžeš id tomu fomuláři nasetovat. $this[personForm]->personId = $id;
Samozřejmě v té třídě si vytvoř public $personId
Ja se omlouvam, ale jde mi z toho hlava trochu kolem. Predesilam, ze i samotne OOP je pro mne dosud terra incognita
Kde se mi v presenteru vezme:
$this[personForm]
kdyz ho nikde nenastavuji?
A tenhle kod prosim udela co?
$form->onSuccess[] = function (Form $form) {
$this->redirect('this');
};
Resp. kam mam ted vrazit nasledujici kod, ktery predtim take patril do Presenteru?
$this->flashMessage('Osoba byla úspěšně uložena.', 'success');
$this->redirect('PersonShow:default', $person->id);
Jeste jednou diky a uz dam dneska opravdu pokoj
Editoval markoska (2. 4. 2022 13:25)
- Marek Bartoš
- Nette Blogger | 1280
$this['personForm']
funguje díky tomu, že
Component
(ze které Control
a Presenter
dědí) implementuje ArrayAccess
. Díky tomu lze přistupovat
k objektu jako k poli. V Nette komponentách je to implementované tak, že
při prvním přístupu k $this['personForm']
se zavolá
createComponent('personForm')
a z ní se v komponentě zavolá
metoda createComponentPersonForm()
Při úspěšném odeslání formuláře se provede redirect na aktuální stránku – brání tak znovuodeslání formuláře při stisknutí F5.
$form->onSuccess[] = function (Form $form) {
$this->redirect('this');
};
Resp. kam mam ted vrazit nasledujici kod, ktery predtim take patril do Presenteru?
Ideálně redirect nechat v presenteru a do komponenty si jej předat
v konstruktoru pomocí anonymní funkce (callable/Closure). Tak zůstane
komponenta nezávislá na konkrétním presenteru. Případně lze na prasáka
zavolat $this->getPresenter()->redirect()
- Marek Znojil
- Člen | 90
Na předávání závislostí do komponent se můžeš podívat tady:
https://doc.nette.org/…n/components#…
Taky je fajn brát v potaz zmínku od @MarekBartoš. Je lepší nechávat události co se má dít po odeslání formuláře na prezenterech.
Pokud budeš mít formulář, který nedědí Nette\Application\UI\Control nebo nepoužívá traitu Nette\SmartObject, můžeš callbacky událostí po odeslání předávat do metody, kterou navrací metoda createComponent<Name>() v prezenteru.
Viz:
https://github.com/…mFactory.php#L28
https://github.com/…resenter.php#L34