Pristup k promenne z url (persistentni) v modulu
- simPod
- Člen | 383
Zdravim, mam v route definovanou promennou <lang>, ke ktere pristupuji v presenteru definovanim
/** @persistent */
public $lang;
a pote ve funkci $this->lang
. Chci se zeptat, zda-li se toho
dá dosáhnout i v modelu, nejak si sahnout na promennou lang, nebo ji tam
musim poslat z presenteru pri volani funkce? Diky
Editoval simPod (24. 12. 2011 13:26)
- Filip Procházka
- Moderator | 4668
Chtěl jsi napsat v modelu, ne?
Nejjednodušší bude to asi nastavit do contextu
protected function startup()
{
parent::startup();
$this->context->parameters['language'] = $this->lang;
}
A pak si ho vytáhnout v potřebném modelu.
Cokoliv čistějšího by bylo docela komplikované, zatím nevím jak to řešit lépe :)
- Nox
- Člen | 378
Nevím jestli na to jdeš dobře
Proto se dělají factory (zjednodušení instanciace); plus předání $context už hezké DI není (jestli by rád). Přesněji se dočteš třeba na Misko Hevery, ale např. třída pak vůbec nedeklaruje své závislosti atd.
Pokud jsou třídy podobné – něměla by se použít dědičnost nebo kompozice atp.? Nevim o jaké přesně třídy jde, to už zase budeš vědět nejlépe asi sám
- simPod
- Člen | 383
ok dobre, ale budu potrebovat v kazdem modelu si sahnout na promennou lang
routy, a abych to nemusel definovat pro kazdy model, tak se mi libilo to reseni
nacpat promennou z presenteru do contextu, akorat nevim jak zaregistrovat
spravne service a jak si zahnout z modelu na context kdzy do presenteru
vlozim $this->context->parameters['language'] = $this->lang;
- saimons
- Člen | 293
Na tohle tema jsem otevrel nedavno jedno tema, ale nikdo moc neodpovedel, jak tohle resit. Ale z me uvahy mi plyne, ze model (at presenteru nebo komponenty) by nemel mit pristup k hodotam z url. Mel by byt predan bud kazde metode zvlast a nebo popripade pro celou tridu controlerem (presentrem). Duvod je podle me ten stejny, jaky je popsany v dokumentaci k DI o sluzbach a tovarnach.
- duke
- Člen | 650
simPod napsal(a):
ok dobre, ale budu potrebovat v kazdem modelu si sahnout na promennou lang routy, a abych to nemusel definovat pro kazdy model…
Tvůj model by měl řešit jen to, co se ho bezprostředně týká, tj.
zpravidla poskytovat data, případně je nějak modifikovat, tedy nikoli
routování. Model může např. umět vracet data v různých jazycích.
K tomu ovšem potřebuje umět přijmout instrukci o tom, v jakém jazyce má
data vracet. K tomu může sloužit např. metoda modelu setLang
(jejíž význam tedy je „odteď mi vracej vše v tomto jazyce“). O tom
v jakém jazyce má model data vracet by měl rozhodovat konkrétní presenter
zpravidla na základě dotazu uživatele, tj. na základě parametrů (do nichž
se – stejně jako do výběru onoho konkrétního presenteru – skrze
routování uživatelův dotaz promítl).
simPod napsal(a):
…a abych to nemusel definovat pro kazdy model…
V presenteru budeš někde mít buď instanciaci modelu, nebo jeho získání jako služby. Co ti brání zapouzdřit tuto operaci do nějaké metody, která krom této operace provede i nastavení jazyka?
- duke
- Člen | 650
Pokud nechceš jazyk předávat u každého dotazu na model (u každého
volání nějaké metody modelu), můžeš přeci použít výše zmíněnou
metodu setLang
, kterou si v modelu můžeš vytvořit a tu pak
zpravidla voláš jen jednou. Navíc si tuto „konfiguraci modelu“ můžeš
zapouzdřit do továrničky, kterou umístíš do nějakého BasePresenteru,
takže v konkrétních presenterech už to vůbec neřešíš, tam jen tu
továrničku voláš.
Z hlediska jednoduchosti není rozdíl v tom, zda jazyk nastavíš zvenčí (injektuješ), nebo zda si ho model někde obstará sám. Injektování zvenčí má výhodu v tom, že nevytváříš zbytečné závislosti, tj. vytváříš model, který je méně závislý na okolí a proto lépe udržovatelný, testovatelný, rozšiřitelný, atp. Doporučuji k přečtení kapitolu o injektování závislostí (tj. dependency injection) v dokumentaci (https://doc.nette.org/…introduction).
- duke
- Člen | 650
Autowiring ti automaticky dosadí pouze parametry, které jsou odkazy na
jiné služby. Běžné parametry ti automaticky nenastaví. Krom toho se
autowiring týká přímo třídy Nette\DI\Container
, a ta
neřeší, zda existuje nějaký persistentní parametr nějakého presenteru.
To je zodpovědnost až toho presenteru, a ten by tedy z logiky věci měl být
tím, kdo modelu hodnotu tohoto parametru sdělí.
Konkrétně to může vypadat tak, že ve třídě BasePresenter
bys měl následující:
/**
* @var string
* @persistent
*/
public $lang;
/**
* @return Model\FooModel
*/
protected function getConfiguredFooModel()
{
return $this->context->fooModel->setLang($this->lang);
}
A ve FooModel.php bys měl:
/**
* @param string language
* @return FooModel provides a fluent interface
*/
public function setLang($lang)
{
$this->lang = $lang;
return $this;
}
- saimons
- Člen | 293
Diky za upresneni, porad jsem mel nakej takovej pocit, ze ziskani toho parametru by taky mohla byt sluzba. Prislo by by mi to pak takove prehlednejsi, ze mam sluzbu, ktera se postarta o prevzeti persistentniho parmaetru a podle DB ji prevede treba na ID (pokud „cs“ neni primarni klic) a pak se preda do tech modelu kde ji potrebuji (autowiringem). Ale je mi jasne ze ziskani toho parametru je vec presenteru.