Formular z presenteru presunout do vlastniho souboru
- Skywalk3r
- Člen | 8
Ahoj, mám v presenteru funkční formulář na přidávání produktů, ale potřebuji tam přidat další formulář a už by presenter nebyl tak přehledný.
Mám to zatím takto
presenter
public function createComponentFormProductAdd(){
return new \FormProductAdd($this->database);
}
app/forms/FormProductAdd.php
<?php
use Nette\Forms\Form;
class FormProductAdd extends Nette\Object {
private $database;
public function __construct(Nette\Database\Context $database)
{
$this->database = $database;
$this->createForm();
}
public function createForm(){
$form = new Nette\Application\UI\Form;
$form->addText('name', 'Název:')
->setRequired('Zadejte prosím jméno');
...
$form->addSubmit('send', 'Přidat');
$form->onSuccess[] = $this->process;
return $form;
}
public function process($form){
try {
...
$this->flashMessage('Produkt vložen.');
/* $this->redirect('this'); */
} catch(Exception $e) {
$form->addError('Při vkládání se vyskytla chyba.'/*.$e*/);
if ($e instanceof \Nette\Application\AbortException) {
throw $e;
}
}
}
}
Ale hlásí mi to chybu
Nette\UnexpectedValueException
Method App\BProductsPresenter::createComponentFormProductAdd() did not return or create the desired component.
Pročpak ? :-)
Tohle řešení mi přijde dobré v tom, že z toho můžu rovnou udělat továrničku pokud bych to chtěl v app použít vícekrát.
Editoval Skywalk3r (16. 2. 2014 16:02)
- Šaman
- Člen | 2666
Ty ale v té továrničce v presenteru vytváříš instanci typu
Nette\Object
, takže ti to skutečně nevytvoří komponentu (což
metoda createComponentXxx zjistí a reklamuje).
Ukázku funkčního řešení najdeš třeba tady.
Ty tam navíc budeš mít samozřejmě i ten konstruktor kvůli předání
závislosti na db.
Pokud bys nechtěl tvořit komponentu, tak bys musel mít ten formulář jako
poděděný Form
a nebo, to je to, co jsi možná chtěl na
začátku vytvořit si továrničku, ale pak v presenteru jen nevytvářej
tovární třídu, ale zavolej její konkrétní metodu, která ti vrátí
nakonfigurovanou instanci Form
.
Editoval Šaman (16. 2. 2014 16:14)
- Skywalk3r
- Člen | 8
Šaman napsal(a):
Ty ale v té továrničce v presenteru vytváříš instanci typu
Nette\Object
, takže ti to skutečně nevytvoří komponentu (což metoda createComponentXxx zjistí a reklamuje).Ukázku funkčního řešení najdeš třeba tady.
Ty tam navíc budeš mít samozřejmě i ten konstruktor kvůli předání závislosti na db.Pokud bys nechtěl tvořit komponentu, tak bys musel mít ten formulář jako poděděný
Form
a nebo, to je to, co jsi možná chtěl na začátku vytvořit si továrničku, ale pak v presenteru jen nevytvářej tovární třídu, ale zavolej její konkrétní metodu, která ti vrátí nakonfigurovanou instanciForm
.
Děkuji, teď už mi to funguje až na jednu drobnost.. pokud chci vykreslit ten formulář pomocí výchozího formátování.. tak na {$form->render()} mi to spadne že $form neni definované ? :-)
Jinak mi šlo pouze o přesun kódu, což by vlastně šlo vyřešit
includem což by ale bylo nehezké :-)
Není mi ale jasná jedna věc.. proč ta metoda createComponent (alias
továrnička) kontroluje jestli vypisuje objekt Control když
zde https://forum.nette.org/…nebo-tovarna do ní jde Nette/Object
a zde https://doc.nette.org/cs/forms#… do ní jde UI/Form
a ani u jednoho to nespadne ?
Pro moje účely bude asi nejlepší ta varianta s UI/Forms, protože tam nemusím vytvářet speciální šablonu pro tu Componentu.. za ten odkaz díky dá se z toho dobře naučit jak vytvářet komponenty :-)
- Skywalk3r
- Člen | 8
Tak jsem se pokusil podle toho UI/Form navodu a hazi to nejakou chybu ale netusim co s tim.
<?php
use Nette\Application\UI\Form;
class FormProductAdd extends Nette\Application\UI\Form {
private $database;
public function __construct(Nette\Database\Context $database)
{
$this->database = $database;
return $this->createForm();
}
public function createForm(){
$form = new Nette\Application\UI\Form;
$form->addText('name', 'Název:')
->setRequired('Zadejte prosím jméno');
...
$form->addSubmit('send', 'Přidat');
$form->onSuccess[] = $this->process;
return $form;
}
public function process($form){
$this->flashMessage('Produkt vložen.');
$this->redirect('this');
}
}
a presenter
public function createComponentFormProductAdd(){
return new \FormProductAdd($this->database);
}
pricemz mi to hazi chybu
Notice
Trying to get property of non-object
v souboru File: …\vendor\nette\nette\Nette\Forms\Form.php:206
Editoval Skywalk3r (16. 2. 2014 17:11)
- Milo
- Nette Core | 1283
Nevoláš konstruktor předka. Btw. hezké čtení https://doc.nette.org/…tion/factory
- Šaman
- Člen | 2666
Jestli chceš jenom přesunout továrničku a obslužnou metodu, tak:
- Vytvoř si FooFormFactory. Ta bude mít metodu (často
create()
), která vytvoří, nakonfiguruje a vrátí hotový formulář. - Tuto si zaregistruj jako službu a normálně ji předej (injectuj) do
presenteru (řekněme do proměnné
fooFormFactory
). - V metodě
createComponentFoo()
pak zavoláš něco jakoreturn $this->fooFormFactory->create();
.
Jinak ta moje ukázka vytváří komponentu s formulářem, nikoliv samotný formulář. Proto ti nefungoval renderer.