Předání parametrů z komponenty zpět do presenteru

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
jan.vince
Člen | 8
+
0
-

Ahoj,

vytvářím všechny svoje formuláře podle postupů v best practise.

Běžně vystačím s továrnami na UI/Form, ale třeba u registračního formuláře, kde se vytváří v DB nový záznam a v onSuccess[] bych potřeboval přesměrovat na stránku s ID nového záznamu (aby bylo možné hned dopsat do dalších formulářů doplňující informace o uživateli).

To ID ale z továrny neumím předat zpět presenteru (a nechci si do formuláře předávat celý presenter – myslím, že by formulář o presenteru neměl nic vědět).

Pro registrační formulář (resp. pro vše, co má předat zpět nějaké parametry) tak používám druhý přístup a vytvářím komponentu na UI/Control, kde si v metodě volané po onSuccess přidám vlastní událost s parametry, které v presenteru potřebuji a tam je zpracuji (to je ten druhý postup v best practise).

Tohle funguje, dělá to přesně, co bych čekal, ale (nějak vnitřně :) mi přijde zbytečné vytvářet UI/Control (a pro něj pak i metodu render() a vlastní šablonu – i když třeba jen jedinou obecnou pro všechny), když bych vystačil jen s jednodušším UI/Form.

Jen ty parametry nějak předat :)

Jak to děláte vy ? Existuje nějaký způsob, jak to z UI/Form předat ?

Předem díky !

Felix
Nette Core | 1199
+
0
-

Ahoj. Hod sem ukazku kodu :) Nebude to tak slozity.

CZechBoY
Člen | 3608
+
0
-

Tak si udělej událost onRegistered kde předáš entitu nově vytvořenýho uživatele.
Viz tvůj odkaz a sekce UI\Control

jan.vince
Člen | 8
+
0
-

@CZechBoY – jasné, to funguje a dělám to přesně takhle. ale přijde mi zbytečné dělat Control na formulář, který vykresluji úplně standardně a nepotřebuji extra šablonu (a takových formulářů mám v aplikaci spoustu).

@Felix – je to přesně ten kus kódu z best practise, který většinou používám:

use Nette\Application\UI;

class MyPresenter extends BasePresenter
{
    /** @var \CategoryForm @inject */
    public $categoryFormFactory;

    protected function createComponentCategoryForm()
    {
        $form = $this->categoryFormFactory->create();
        $form->onSuccess[] = function (UI\Form $form) {
            $this->redirect('this');

			// Tady bych potřeboval přesměrovat na stránku s ID - ale jak to ID předat ?

        };

        return $form;
    }
}
CZechBoY
Člen | 3608
+
0
-

Tak to nedělej jako Control, to je jedno. Jen musíš podědit Nette\Object.

F.Vesely
Člen | 369
+
0
-

Tip: Nemusis si vytvaret zadnou sablonu, pokud chces vykreslit jen formular.

public function render(){
	$this['form']->render();
}
Jan Mikeš
Člen | 771
+
0
-

@jan.vince docela jednoduse a elegantne to ja pouzivam takto:

Presenter:

	protected function createComponentLustrationForm(XyzForm\FormFactory $factory)
	{
		return $factory->create(function($form, MyEntity $entity) {
			$form->presenter->redirect("MyPresenter:detail", [$entity->id]);
		});
	}

FormFactory:

	// private $callback; // Spatny pristup!!


	public function create(callable $callback)
	{
		// $this->callback = $callback; // Spatny pristup!

		// inputs ...

		// $this->onSuccess[] = $this->process; // Tim, ze nevyuzijeme property tridy je potreba vyuzit anonymni fci

		$this->onSuccess[] = function($form, $values) use ($callback) {
			$this->process($form, $values, $callback);
		};
	}

	public function process($form, $values, $callback)
	{
		$entity = $this->mySuperModel->superMethod($values); // returns instance of MyEntity

		call_user_func($this->callback, $form, $entity);
	}

Samozrejme misto predavani pres konstruktor si muzes udelat svuj vlastni event nebo setter, toto je pouze nejkratsi mozny zapis.

Edit: kod upraven na zaklade poznamky od @DavidMatějka

Editoval Lexi (1. 12. 2015 12:15)

David Matějka
Moderator | 6445
+
+2
-

@Lexi
Ukladani parametru create metody do clenskych promennych tovarny je spatne, factory ma byt bezstavova. Napriklad kdybys na jedne strance mel dva formulare, tak to nebude fungovat. spravne reseni za pouziti tovarny je treba

public function create(callable $callback)
{
    // inputs ...

    $form->onSuccess[] = function($form, $values) use ($callback) {
		$this->process($form, $values, $callback);
	};
}

public function process($form, $values, $callback)
{
    $entity = $this->mySuperModel->superMethod($values); // returns instance of MyEntity

    call_user_func($callback, $form, $entity);
}
Jan Mikeš
Člen | 771
+
0
-

@DavidMatějka to jsem si vubec neuvedomil, diky za tip!

jan.vince
Člen | 8
+
0
-

Díky všem za info !

Zkoušel jsem UI/Form od @Lexi (a @DavidMatějka ), to funguje bez problémů.

A díky @F.Vesely za tip s renderováním.