Vygenerovat link ze SystemContaineru
- josef.sabl
- Člen | 153
Když jsem v Presenteru, napíšu:
class BasePresenter
{
function renderDefault()
{
$link = $this->link("Hello:world");
}
}
Dejme tomu, že ale v presenteru napíšu:
class BasePresenter
{
function renderDefault()
{
$link = foo($this->context);
}
}
function foo($context)
{
return ???
}
Co mám zapsat místo otazníčků abych dostal link? Díky.
- josef.sabl
- Člen | 153
Felix napsal(a):
Ale velmi nedoporucuju! Je to spatny navrh!
function foo($context) { return $context->application->presenter->link(...); }
Díky, tyhle odpovědi jsem samozřejmě čekal (špatný návrh) :o)
- echo
- Člen | 134
Tento „špatný návrh“ používá interně samo Nette. :o) Viz. https://api.nette.org/…ent.php.html#318
- Nox
- Člen | 378
Proč tam máte celý kontejner, když v tom pak hledáte jen presenter, nestačil by rovnou presenter? Pak byste mohli mít typehint na PresenterComponent: pak tam projde cokoli co umí PresenterComponent::link() a funkce se nemusí rýpat v kontejneru a hledat co použít.
Další možnost (imho lepší než $context, horší jak PresenterComponent):
<?php
$presenter = $this;
$linkBuilder = function($destination, $args = array()) use($presenter) {
return $presenter->link($destination, $args);
};
foo($linkBuilder);
// php5.4+
$linkBuilder = function($destination, $args = array()) {
return $this->link($destination, $args);
};
?>
- Filip Procházka
- Moderator | 4668
echo napsal(a):
Tento „špatný návrh“ používá interně samo Nette. :o) Viz. https://api.nette.org/…ent.php.html#318
Na tom nic špatného není.
- Felix
- Nette Core | 1247
echo napsal(a):
Tento „špatný návrh“ používá interně samo Nette. :o) Viz. https://api.nette.org/…ent.php.html#318
To je ale neco jinyho. Ne ze jdu pres Container → App → Controller.
- echo
- Člen | 134
Felix napsal(a):
echo napsal(a):
Tento „špatný návrh“ používá interně samo Nette. :o) Viz. https://api.nette.org/…ent.php.html#318
To je ale neco jinyho. Ne ze jdu pres Container → App → Controller.
Mi to přijde principiélně to samý. Akorát jde o hierarchii komponent a ne o hierarchii služeb (konteiner). viz. tam to $this->lookup(‚…UI\Presenter‘).
Obojí ti to vrátí pokaždé jinou třídu/presenter (v závislosti na akci). IMHO nic špatného na tom není.
Editoval echo (3. 4. 2013 14:40)
- josef.sabl
- Člen | 153
Jak byste mně, Nette začátečníkovi, resp. uživateli Nette střev neznalého, popsali, co je to container a proč je špatně, abych jen na základě jeho dostupnosti měl mít možnost vygenerovat link podle routeru, který je v bootstrapu konfigurován na úrovni právě tohoto containeru:
$container->router[] = new Route('index.php', 'Homepage:default', Route::ONE_WAY);
$container->router[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
Díky
PS: Nejsem hledač nejkratší cesty. Kdybych byl, tak tam prdnu
<a href='/hello/world'>
a je vymalováno :o)
Editoval josef.sabl (3. 4. 2013 15:22)
- josef.sabl
- Člen | 153
bazo napsal(a):
a preco chces vobec v bootstrape tvorit odkazy?
V bootstrapu netvořím odkazy. V bootstrapu na úrovni containeru definuju routy. Proto je mi divné, že na úrovni containeru později nesmím router použít k vygenerování linku. Ale jak říkám, nejsem žádný nette odborník a rád se nechám vyvést z omylu.
- josef.sabl
- Člen | 153
bazo napsal(a):
tak sa opytam inak, co vlastne chces dosiahnut?
Odpovědi na mou otázku :-)) Co je container a proč je špatně, aby tvořil odkazy. Nic nerozporuju, ale chci to nějak víc pochopit.
To, co jsem v aplikaci potřeboval, jsem vyřešil. Dotaz byl: mám context,
jak získám odkaz.
Ale změnilo se to v akademickou debatu, tak se akademicky ptám.
Editoval josef.sabl (3. 4. 2013 16:13)
- Nox
- Člen | 378
„Žán, podejte mi to piáno. Mám na něm doutník.“
Každá část aplikace by měla mít závislostí tak akorát aby nedělala co nemá dělat ale zase nebyla příliš svázaná. Mělo by být vidět jaké a pokud jde z toho odhadnout proč, tím líp. Čím menší množství závislostí, tím jednodušeji se bude upravovat, vytvářet mocky atd.
Pokud část aplikace potřebuje něco co ji vytvoří odkaz, pak je nejvýhodnější předat to a jen to, co vytváří odkaz. Ta část málokdy potřebuješ přesně ten kontejner, celý kontejner.
Jednodušší potom bude i znovupoužitelnost: pokud chceš použít třídu X která má závislost na Y, je pravděpodobné, že cílová aplikace bude taky disponovat něčím jako Y. Ale pokud to ta X příjmá obalené v chuchvalci nějakých dalších irelevantních objektů, bude to potřeba více upravovat.
Dále si vezmi, že tam budeš chtít třeba předat jinou instanci (nemusí být jen u testů). U kontejneru budeš muset vytvoří nový kontejner, do něj dát sekci application, do ní presenter; přitom by stačilo dát prostě ten presenter.
- josef.sabl
- Člen | 153
Nox napsal(a):
„Žán, podejte mi to piáno. Mám na něm doutník.“
Každá část aplikace by měla mít závislostí tak akorát aby nedělala co nemá dělat ale zase nebyla příliš svázaná. Mělo by být vidět jaké a pokud jde z toho odhadnout proč, tím líp. Čím menší množství závislostí, tím jednodušeji se bude upravovat, vytvářet mocky atd.
Pokud část aplikace potřebuje něco co ji vytvoří odkaz, pak je nejvýhodnější předat to a jen to, co vytváří odkaz. Ta část málokdy potřebuješ přesně ten kontejner, celý kontejner.
Jednodušší potom bude i znovupoužitelnost: pokud chceš použít třídu X která má závislost na Y, je pravděpodobné, že cílová aplikace bude taky disponovat něčím jako Y. Ale pokud to ta X příjmá obalené v chuchvalci nějakých dalších irelevantních objektů, bude to potřeba více upravovat.
Dále si vezmi, že tam budeš chtít třeba předat jinou instanci (nemusí být jen u testů). U kontejneru budeš muset vytvoří nový kontejner, do něj dát sekci application, do ní presenter; přitom by stačilo dát prostě ten presenter.
Díky za piáno, já ale nechtěl ani ten doutník :-) To, co popisuješ je DI. Vím, co je DI a souhlasím, že je to dobrá věc (nejsem bojovník proti DI :-).
A omlouvám se, jestli jsem se kohokoli dotknul.
Mám jen zmatek v tom, jakou roli by měl mít presenter a jakou roli by měl mít container. Pro mě je context (container) taková ta věc, co tam jsou různý zajímavý věci a presenter je pro mě objekt, který vyřizuje aktuální požadavek. Application jsem nějak vůbec nepobral :)
Když to vezmu z mého pohledu (který je zcela jistě pokřivený a snažím se ho tady narovnat), tak link by měla tvořit šablona, která jeho informační hodnotě zapsané nějakým identifikátorem anebo polem, přiřadí konkrétní formát/podobu.
Budu teda docela konkrétní: Ve zmíněné aplikaci je služba (Cron), která se pravidelně podívá do konfigurace, kde je seznam workerů, kteří se mají v daný okamžik spustit. Např. rozeslání newsletterů zákazníkům.
Každý worker je nějaká třída, která dědí toto:
abstract class Worker
{
protected $context;
public function __construct(\Nette\DI\Container $container)
{
$this->context = $container;
}
abstract function execute();
}
A pak mám třídu NewsletterSender, která posílá maily, jejichž obsahem jsou mimo jiné odkazy. A jsme doma, mám kontext, potřebuju odkaz. Co je tedy špatně?
- David Matějka
- Moderator | 6445
„jednoduche“ generovani linku zatim jinak nez pres presenter nejde (resi
se to tady https://forum.nette.org/…nerator-todo
takze nekdy v budoucnu by mela byt sluzba na tvorbu odkazu..)
zatim jsou tedy 2 moznosti: bud se nejak dostat k presenteru
nebo (a to bude lepsi) pouzit router a metodu constructUrl (viz https://api.nette.org/…IRouter.html#…)
- bazo
- Člen | 620
tak staci hned povedat, ze chces tvorit odkazy mimo sablon a presenterov. potom by sa tu nezvrhla ziadna akademicka debata.
slo by to nejak takto
function link(IRouter $router, \Nette\Http\UrlScript $url){
$params = [...];
$appRequest = new \Nette\Application\Request($destination, \Nette\Http\IRequest::GET, $params);
$link = $router->constructUrl($appRequest, $url);
}
- josef.sabl
- Člen | 153
matej21 napsal(a):
„jednoduche“ generovani linku zatim jinak nez pres presenter nejde (resi se to tady https://forum.nette.org/…nerator-todo takze nekdy v budoucnu by mela byt sluzba na tvorbu odkazu..)
zatim jsou tedy 2 moznosti: bud se nejak dostat k presenteru
nebo (a to bude lepsi) pouzit router a metodu constructUrl (viz https://api.nette.org/…IRouter.html#…)
Ach, dokonalá odpověď, díky ti!
- josef.sabl
- Člen | 153
bazo napsal(a):
tak staci hned povedat, ze chces tvorit odkazy mimo sablon a presenterov. potom by sa tu nezvrhla ziadna akademicka debata.
slo by to nejak takto
function link(IRouter $router, \Nette\Http\UrlScript $url){ $params = [...]; $appRequest = new \Nette\Application\Request($destination, \Nette\Http\IRequest::GET, $params); $link = $router->constructUrl($appRequest, $url); }
Díky i tobě za ukázku, jak použít router.
PS: Akademické debaty jsou prima, člověk se něco doví ;-)
Editoval josef.sabl (3. 4. 2013 17:25)