Jak správně předat do komponenty parametr

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Jiří Nápravník
Člen | 710
+
0
-

Jaký je nejlepší způsob nastavení komponenty (využívám generované továrny). Konkrétně mám například formulář (přidání něčehoa zároveň editace). A potřebuji tam předat např. tu entitu pro editaci a předvyplnit formulář. Přišel jsem v podstatě na tři postupy, viz níže a moje otázka zní, který je správný, resp. doporučovaný. Pokud byste uvedli co je dobře a co špatně budu jen rád:-)

1. konfigurace přes neon
tady se mi příliš nelíbí že v podstatě konfiguračná soubor znásilňuju k programování a nevím, zda to je to správné využití. + s tou konfigurací se celkem napíšu více než se ostatními (viz níže)

services:
	-
		implement: ArticleModule\Form\IArticleEditFormFactory
		class: ArticleModule\Form\IArticleForm
		parameters: [articleToEdit]
		setup:
			- setArticleToEdit(%articleToEdit%)

v presenteru pak jen:

	protected function createComponentForm()
	{
		//$this->articleToEdit je nastavena v action pro editaci
		return $this->articleFormFactory->create($this->articleToEdit);
	}

2. setter přímo v továrničce
v neonu jen klasika

services:
	- ArticleModule\Form\IArticleEditFormFactory

presenter:

	protected function createComponentForm()
	{
		//$this->articleToEdit je nastavena v action pro editaci
		$form = $this->articleFormFactory->create();
		$form->setArticleToEdit($this->articleToEdit);
		return $form;
	}

3. setter už v action
Tenhle případ nastavené komponenty z action, co jsem vyčetl není úplně správný, protože to prý není lazy-loading a vytvoří se třeba ta proměnná někdy zbytečně. Je to pravda nebo jsem to špatně pochopil? Případně řešilo by to předání do render?

neon stejný jako ve 2. případě a presenter:

	public funtion actionEdit($id){
		$this['form']->setArticleToEdit($this->model->findArticle($id));
	}

	protected function createComponentForm()
	{
		return $this->articleFormFactory->create();
	}
Oli
Člen | 1215
+
0
-

Nevim jestli je nejlepší, ale já používám ten poslední způsob. Ono asi záleží na použití. Mám většinu formulářů v actionEdit($id = null), takže buď ten parametr je a pak se to nevykreslí zbytečně a nebo není a pak jet o irelevantní (respektive vubec se ta $this['form']->setArticleToEdit($this->model->findArticle($id)); nezavolá).

Nejvíc se mě ale asi líbí ta 2.

David Matějka
Moderator | 6445
+
0
-

4. zadnej setter

article predavam rovnou do konstrutoru ArticleForm, v neonu staci vyhodit setup a pridat

arguments: [%articleToEdit%]
Oli
Člen | 1215
+
0
-

Btw. mají jednotlivé možnosti nějaký výhody nebo nevýhody? Jediná @matej21 verze mě přijde lepší z hlediska toho, že nemusím psát žádnej setter ⇒ kratší kod. Jinak mě to přijde prašť jak uhoď.

Jiří Nápravník
Člen | 710
+
0
-

matej21: to vypadá zajímavě, díky. Jen je tam škoda, že jak se zbavím setteru, tak nemůžu kontrolovat jednoduše typehint

Oli: jo v podstatě to jsou všechno tři stejné věci jen jinak pojaté a zajímá mě, co je správnější.

a jeste jak to je u třetí metody s tím, že to pak není ideální, že pak není továrna lazy?

Jiří Nápravník
Člen | 710
+
0
-

Tak jsem začál používat to řešení od matej21, a chci se zeptat, je nějak možné v tomhle řešení nastavit typehint v constructoru Objekt $object = NULL, zkrátka aby se dal povolit, že rpojde jen to co požaduji nebo null?

Potřeboval bych, abych měl nějaký takový konstruktor, zkrátka aby byl ten parametr vyplněný v parameters/arguments na posledním místě:

//facade je autowiringem z DIC
public function __construct(Facade $facade, Entity $adToEdit = NULL)

K mému překvapení funguje tohle:

public function __construct(Entity $adToEdit = NULL, Facade $facade)

či-li volitelného parametru (resp. sedí typehint nebo null) dosáhne, ale volitelné parametry patří na konec halvičky metody a dokonce ani IDE se to nelíbí. Je nějaké řešení?

David Matějka
Moderator | 6445
+
0
-

aby to bylo na poslednim miste, melo by stacit do configu:

arguments: [..., %articleToEdit%]

ja teda v pripade editovacich formularu (komponent) pozaduju tu entitu vzdycky. jinde, kdyz chci mit ten parametr volitelny, tam dam proste NULL, stejne jak uvadis v druhem pripade, a neresim to :)

Jiří Nápravník
Člen | 710
+
0
-

Ty tři tečky jsem našel v dokumentaci nakonec, ale bohužel, musím psát tolik teček, kolik chci automaticky doplnit služeb, myslel jsem, že stačí tři tečky za vše, ale bohužel:/ Což není úplně ideální, když pak přidám závislost v konstruktoru, budu muset sahat zase na neon…

Já to mám jako editační a zároveň přidávací formulář, tam jeidně podstrčit prázdnou entitu…

jinde, kdyz chci mit ten parametr volitelny, tam dam proste NULL, stejne jak uvadis v druhem pripade, a neresim to :)

Jak myslíš teď? Že tám nedáš typehint a tím pádem to projde bez problém us nullem, nebo dáváš ten s tím NULLem na začátek, viz tohle:

public function __construct(Entity $adToEdit = NULL, Facade $facade)
David Matějka
Moderator | 6445
+
0
-

jo, tohle

public function __construct(Entity $adToEdit = NULL, Facade $facade)
Jiří Nápravník
Člen | 710
+
0
-

Ještě je tu možnot nacpat ten typehint do create, ale pak se musí dát i do neonu a to taky není moc pěkné. Myslím, že by ale bylo fajn, kdyby nette umělo, pokud nadefinuji ten parametr v create jako přednastavený, tak že by to ty argumenty přeházelo tak, že by ho dalo nakonec… Jestli se v tom vyznám a budu mít někdy čas možná zkusím pull request