Vložení vlastního objektu do formuláře

- Johny12369
 - Člen | 21
 
Zdravím, je možné si uložit vlastní objekt, který neimplementuje rozhraní IComponent do objektu formuláře v metodě create? V mém případě bych si chtěl uložit 2 Doctrine Entity objekty, aby byly použitelné v metodě …FormSubmited, kdy si je potřebuji ukládat. Posílám si je z presenteru, jako parametry do metody create, a nemohu si je uložit přes $form[‚firma‘] = $firma;, protože to neimplementuje IComponent, a když si je uložím v metodě create do privátního atributu továrničky formuláře, tak při odeslání jsou najednou tyto atributy null.
Dělat to přes addHidden, kam si uložím pouze ID firmy a po odeslání formuláře si teprve Entity objekt pomocí tohoto ID vyhledám se mi zdá míň praktický.
Díky moc za odpověď.

- David Matějka
 - Moderator | 6445
 
ahoj to fungovat nebude a neni to dobry napad. radeji vyres, proc je po odeslani ta hodnota null. ukaz kod presenteru a tovarny, treba poradime :)

- Johny12369
 - Člen | 21
 
Presenter:
<?php
use App\Model\Firmy;
use App\Forms\NovyEmailFormFactory;
class FirmyPresenter extends Presenter
{
	/** @var Firmy */
	private $firma;
	/** @var NovyEmailFormFactory @inject */
	public $novyEmailFactory;
	public function renderDetail($id)
    {
		$er_firmy = $this->em->getRepository(Firmy::class);
		$this->firma = $er_firmy->findOneBy(["id" => $id]);		//Do atributu si najdu podle ID objekt té firmy
	}
	/**
	 * NovyEmail form factory.
	 * @return Nette\Application\UI\Form
	 */
	protected function createComponentNovyEmailForm()
	{
		\Tracy\Debugger::barDump($this->firma, "Firma");	//Při načtení stránky je atribut firma správně, ale po odeslání formuláře je tady nejednou null
		$form = $this->novyEmailFactory->create($firma);
		$form->onSuccess[] = function() {
			$this->handleSetFlashMessage("success", "E-mail byl vytvořen a odeslán.", "this");
		};
		$form->onError[] = function() {
			$this->handleSetFlashMessage("error", "Nastala chyba, viz formulář.");
		};
		return $form;
	}
?>
Factory:
<?php
use App\Model\Firmy;
class NovyEmailFormFactory
{
	use Nette\SmartObject;
	/** @var Firmy */
	private $firma;
	/**
	 * @param App\Model\Firmy $firma
	 * @return Form
	 */
	public function create($firma)
	{
		if (empty($this->firma)) {
			$this->firma = $firma;
		}
		\Tracy\Debugger::barDump($this->firma);		//Při vytvoření opět správně a po odeslání null (obě proměnné $firma a $this->firma)
		$form = $this->factory->create();
		$form->addText('zprava')
				->setRequired('Prosím zadejte zprávu.');
		$form->addSubmit('send', 'Odeslat');
		$form->onSuccess[] = [$this, 'novyEmailFormSubmitted'];
		return $form;
	}
	public function novyEmailFormSubmitted(Form $form)
	{
		$values = $form->getValues();
		\Tracy\Debugger::barDump($this->firma);	//Tady po odeslání null
	}
}
?>
Při načtení stránky se mi v bardump vypíšou všechny atributy správně jako objekty Firmy, ale jak vyplním formulář a kliknu na Odeslat tak se všechno změní na null. Všechny ostatní atributy jako EntityManager, FormFactory si deklaruju správně, to jsem jenom do kódu nedal, aby tam bylo to hlavní.

- petr.jirous
 - Člen | 128
 
render metody se zpracovavaji az po formularich… koukni na
zivotni cyklus presenteru do dokumentace… v tvem pripade by melo stacit
inicializovat property firma uz v actionDetail

- David Matějka
 - Moderator | 6445
 
mimochodem, factory by melo byt bezstavove, spravne by to melo byt treba pres closuru:
<?php
use App\Model\Firmy;
class NovyEmailFormFactory
{
    use Nette\SmartObject;
    /**
     * @param App\Model\Firmy $firma
     * @return Form
     */
    public function create($firma)
    {
        $form = $this->factory->create();
        $form->addText('zprava')
                ->setRequired('Prosím zadejte zprávu.');
        $form->addSubmit('send', 'Odeslat');
        $form->onSuccess[] = function ($form) use ($firma) {
			$this->novyEmailFormSubmitted($form, $firma);
		};
        return $form;
    }
    public function novyEmailFormSubmitted(Form $form, $firma)
    {
        $values = $form->getValues();
    }
}
				
- Johny12369
 - Člen | 21
 
Já vím, ale nenapadlo mě vůbec, jak to udělat jinak. Díky :)
David Matějka napsal(a):
mimochodem, factory by melo byt bezstavove, spravne by to melo byt treba pres closuru:
<?php use App\Model\Firmy; class NovyEmailFormFactory { use Nette\SmartObject; /** * @param App\Model\Firmy $firma * @return Form */ public function create($firma) { $form = $this->factory->create(); $form->addText('zprava') ->setRequired('Prosím zadejte zprávu.'); $form->addSubmit('send', 'Odeslat'); $form->onSuccess[] = function ($form) use ($firma) { $this->novyEmailFormSubmitted($form, $firma); }; return $form; } public function novyEmailFormSubmitted(Form $form, $firma) { $values = $form->getValues(); } }