Továřnička s parametrem z actiony

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

Zdravím,

v poslední době jsem často narážel na situaci, kdy do actiony předáván IDčko, které potřebuju dostat do továrničky. První řešení je:

private $id;

public function actionEdit($id) {
	$item = $this->repository->get($id);
	if (!$item) throw new BadRequestException();
	$this->id = $id;
}

public function createComponentMyComponent() {
	return new MyComponent($this->id);
}

Toto řešení se mně však moc nelíbí, protože v továrničce spoléhám na to, že je proměnná $id nastavená. Navíc pokud se presenter rozroste až příliš a přistupuju přes $this->id z 10 různých akcí, renderů a jiných metod tak vlastně vůbec není na první pohled patrné kdo tuto proměnou nastavil.

Jde to vylepšit druhým způsobem, přes setter

public function actionEdit($id) {
	$item = $this->repository->get($id);
	if (!$item) throw new BadRequestException();
	$this['myComponent']->setId($id);
}

public function createComponentMyComponent() {
	return new MyComponent();
}

Jenže u komponenty nedává smysl, aby se vůbec vytvářela, pokud jí nepředám IDčko, tím pádem je ID povinné a mělo by být v konstruktoru. Sice se mně tento způsob líbí nejvíc, ale pořád to není ono.

To mně dovedlo k tomu používat třetí způsob:

public function actionEdit($id) {
	$item = $this->repository->get($id);
	if (!$item) throw new BadRequestException();
	$this->addComponent(new MyComponent($id), 'myComponent');
}

Jenže když chci používat komponentu i v jiných akcích, tak ji musím do všech akcí zase přidávat a pokud tam nastavuju vždycky nějaké hodnoty přes settery, tak bych musel vždy zapisovat settery na komponentu ve všech akcích kde bych komponentu přidával. Což je taky naprd.

A tak jsem uvažoval, že nejlepší by bylo předávat si parametr z latte do továrničky. Vzpomněl jsem si však, že když jsem s nette začínal tak jsem někde na fóru četl, že se tomu mám vyhýbat pokud to jde.

čtvrtý způsob

public function actionEdit($id) {
	$this->template->id = $id;
}

public function createComponentMyComponent($id) {
	return new MyComponent($id);
}

latte

{control myComponent-$id}

Ze všech uvedených příkladů mně tento připadá nejlepší. Je pravda, že je lepší se tomu způsobu vyhýbat? Z jakého důvodu? A který způsob používate vy?

Dík za odpovědi

Editoval ondrej256 (4. 10. 2016 19:11)

CZechBoY
Člen | 3608
+
+1
-

Ten poslední způsob funguje jen přes Multiplier, ne?

Co se děje v konstruktoru tý komponenty (není to továrnička nejspíš, protože děláš novou instanci ručně)?
Můžeš použít metodu startup a vzít si parametr ručně z $this->getParameter('id');, potom v action ten parametr ještě zvaliduješ.

Já obecně používám 1–2 action metody na 1 presenter, takže to ID vlastně beru jakoby bylo v konstruktoru (potom asi něco jako tvoje komponenta) a jedná se o jednu jedinou akci, maximálně s dotažením např. grafu přes ajax.

Eda
Backer | 220
+
0
-

Nejvhodnější a nejčistší je z mého pohledu způsob jedna. Je ale nutné mít „malé“ presentery, aby v tom právě nebyl chaos. Ideální je mít presentery jen o jedné akci. Pak je všechno přehledné a čisté.

K druhému způsobu: tady mi trochu překáží přístup ke komponentě pomocí array accessu a stringového identifikátoru. Když se tomu dá vyhnout, tak to radši nepoužívám. Protože pak je název komponenty vlastně už na třech místech – v názvu tovární metody, v latte a nově i ve stringu.

Třetí způsob se mi nezdá vhodný právě z toho důvodu, že tam chybí ta tovární metoda. Když tam je, a vidím pak někdy v latte {control xy}, tak stačí pak jen vyhledat v PHP strormu pomocí jednoduché zkratky příslušnou metodu a okamžitě jsem na místě, kde se control vytváří. Navíc tam pak pomocí Kdyby/Autowire můžu injectnout továrnu na samotný form a nezanesu si další členskou proměnnou samotný presenter.

Ad čtvrtý způsob: tady koukám mícháš dvě věci – a) předání parametru render metodě komponenty ({control myControl $param}) a b) vytvoření komponenty pomocí multiplieru ({control myControl-$param}).

  1. použití multiplieru je ok, ale sem vhodné není.
  2. předávání parametru render metodě bych se rozhodně vyhl. Už několikrát se nám vymstilo ve firmě předávat cokoliv do render metody komponent přes šablonu. Protože když pak rozšiřuješ komponentu o další parametry/funkčnost, tak se to nedá pohodlně refaktorovat a vzniká chaos v tom, co se předává do komponenty přes konstruktor a co přes render metodu.