Predanie premennej z action do komponenty

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

V akcii preseteru ziskam nejake ID

<?php
class PagePresenter extends BasePresenter
{
  public function actionDefault()
  {
    ...
    $pageId = $model->getId($url);
  }
}
?>

V layoute mam „parametrizovane“ volanie widgetu

@layout.php
<someHtml>
  {control menu 2}
</someHtml>

No a potom tu mam komponent (teda control), kde sa zariadim podla hodnoty parametra

<?php
class MenuControl extends Control
{
  public function render($id)
  {
    ...
  }
}
?>

No ako je uz zrejme, potrebujem si nejakym elegantnym sposobom ID z akcie predat do controlu. Jeho „znovuziskanie“ neprichadza do uvahy, nakolko sa taha z ORM co je narocna operacia a je kravina ho ziskavat 2× za request.
PLS help.

David Grudl
Nette Core | 8133
+
0
-

v presenteru:

$this['menu']->setId($pageId);

samozřejmě control musí mít metodu setId()

PetrP
Člen | 587
+
0
-

David Grudl napsal(a):

v presenteru:

$this['menu']->setId($pageId);

samozřejmě control musí mít metodu setId()

Ale jenom v případě když se bude control vypisovat pokaždé. Protože kdyby se vypisoval jen někdy tak bys ho zbytečně tímhle vytvořil. Pak by bylo lepší hodit to id do nějaké dostupné property na presenteru a v control si to vytáhnout až když budeš potřebovat.

$this->getPresenter()->getPageId();

Taky mě napadá když je získání ID tak náročná operace tak si jí v modelu cachovat. Bud runtime nebo i třeba na několik hodin.

Jinak převod url na id by si měl realizovat v routách, třeba nějak takto.

Route::addStyle('pageId', NULL);
Route::setStyleProperty('pageId', Route::PATTERN, '[a-zA-Z0-9-_]*');
Route::setStyleProperty('pageId', Route::FILTER_OUT, callback($model, 'getPageUrl'));
Route::setStyleProperty('pageId', Route::FILTER_IN, callback($model, 'getPageId'));

Metoda getPageUrl dostane ID a vrátí url a getPageId dostane url a vrátí ID. Výhoda je že jsi od tvorby url úplné odříznutej.

$presenter->link(..., array('pageId' => 5)); // vygeneruje adresu podle routeru
Ondřej Mirtes
Člen | 1536
+
0
-

PetrP: To, cos navrhnul, vytváří závislost na Presenteru, aby měl metodu getPageId() a to není správně.

PetrP
Člen | 587
+
0
-

Jasně ale to co psal david vytváří závislost na té componeně aby měla metodu setId a aby jí presenter naplnil datama. Když je komponenta určená pro práci z presenterem tak nevidím důvod proč by si z něho nemohla tahat data. Zvláště v případě kdy by nevznikala vždycky ale jen někdy, a tudíž bys jí zavoláním $this['menu'] zbytečně vytvořil.

Ale hlavně navrhuju řešení přes router takže by si pak vytáhl ID přes $presenter->getParam('pageId') a to považuju za lepší.

Ondřej Mirtes
Člen | 1536
+
0
-

„závislost na té componeně aby měla metodu setId“ – ježiši, když používám nějakou komponentu s konkrétním API, a toto nastavení potřebuje, tak snad s tím setterem můžu počítat :)

Naopak getPageId na straně Presenteru je nadbytečná závislost a musel bych pamatovat na to, aby každý Presenter, který tuto komponentu chce využívat, měl navíc metodu getPageId(). A co kdybych tuto komponentu chtěl využívat nějak jinak? Třeba jen jako subkomponentu nějaké jiné komponenty?

Pokud se mi v nějaké action (v příkladu výše action default) komponenta vykresluje a to vždy, tak není důvod si ji nevytvořit už v action části. Kdyby to vykreslení v určitém view bylo podmíněné nějakým stavem, můžu tento stav kontrolovat i v té action části, abych nezatěžoval stroj nadbytečným vytvořením komponenty.

Vytahovat si parametr přes $presenter->getParam('pageId') je snad ještě horší řešení – co kdybych jí chtěl používat ve dvou Presenterech a v každém se ten parametr jmenoval jinak? :o)

PetrP
Člen | 587
+
0
-

Ondřej Mirtes napsal(a):

Pokud se mi v nějaké action (v příkladu výše action default) komponenta vykresluje a to vždy, tak není důvod si ji nevytvořit už v action části. Kdyby to vykreslení v určitém view bylo podmíněné nějakým stavem, můžu tento stav kontrolovat i v té action části, abych nezatěžoval stroj nadbytečným vytvořením komponenty.

Právě mluvím přímo o případu kdy se nevykresluje vždy. Problém je že kontrolovat ten stav může bejt složité. Protože komponenta může vzniknout i mimo tenhle stav, např je na ní z url zavolanej signál.

Vytahovat si parametr přes $presenter->getParam('pageId') je snad ještě horší řešení – co kdybych jí chtěl používat ve dvou Presenterech a v každém se ten parametr jmenoval jinak? :o)

Nesouhlasím tohle je podle mě nejlepší řešení. Url adresu řeším jen v routeru. A id si předávám například při vytváření komponenty.

//OnePresenter
protected function createComponentMenu()
{
	$m = new Menu;
	$m->setId($this->getParam('pageId'));
	return $m;
}
//TwoPresenter
protected function createComponentMenu()
{
	$m = new Menu;
	$m->setId($this->getParam('pageIdADnesJsemSeRozhodlZeBuduPouzivatJinejIdentifikatorProPage'));
	return $m;
}
// to samodrejme predpoklada ze `pageIdADnesJsemSeRozhodlZeBuduPouzivatJinejIdentifikatorProPage` si budes muset v routrach taky resit. Ale když to tak chces ;]

Proste v aplikaci pracuju jen z ID, a to ze se v url misto toho zobrazuje ‚super-seo-url‘ je mi uplne putna.

Jinak aby jsme si uplně rozuměli Menu::setId() považuju taky za lepší řešení, jen nesouhlasím s $this['menu']->setId() volat nekde v actionDefault.

(asi bych teda metodu přejmenoval na setCurrentPageId() ;])

Editoval PetrP (21. 1. 2010 11:34)