Jak přidat služby do basePresenteru
- Siam
- Člen | 54
Dobrý den, udělal jsem si komponentu ankety, která přijímá model, httpRequest a httpResponse. Továrničku vytvářím a plním v presenterech pomocí inject metod, například takto:
<?php
/** @var Nette\Http\Response */
private $httpResponse;
public function injectHttpResponse(Nette\Http\IResponse $httpResponse)
{
$this->httpResponse = $httpResponse;
}
?>
A to pak předávám do továrničky na tu anketu a funguje to tak jak má.
Chtěl bych to ale použít v basePresenteru, abych to nemusel vytvářet v každém presenteru, když to chci generovat na všech stránkách. Když to tam ale dám, tak mi to nefunguje. Můžu se zeptat proč?
Do layout.latte se to pak snažím předávat v metodě beforeRender, ale v tom problém není.
- huttarichard
- Člen | 4
private $httpResponse;
měl by si zaměnit za
protected $httpResponse;
Private platí pro danou třídu, nikoliv pro třídy co jí dědí :) Protected umožnuje přístup!
Editoval huttarichard (15. 10. 2012 14:47)
- studna
- Člen | 181
Pomohlo by, kdybys uvedl chybovou hlášku nebo co vlastně nefunguje. Případně celý kód, jak sestavuješ tu komponentu. Nevykresluješ ji přes {control}?
Do layout.latte se to pak snažím předávat v metodě beforeRender, ale v tom problém není.
Možná saháš do BasePresenteru po private proměnné.
- MartinitCZ
- Člen | 580
Spíš bych se zamyslel na použítím. Když chceš injectovat
v BasePresenteru (tedy tahat to i tehdy, nebudeli třeba), tak to už skoro
můžeš rovnou použít services locator
($this->context->httpResponse
).
- Siam
- Člen | 54
Já akorát hledám způsob jak to udělat. Měl jsem za to, že se to nebude tahat ikdyž to není potřeba. Potřebuje prostě dostat do továrničky nějak model, httpResponse a httpRequest, abych tam s nimi mohl pracovat.
Že nefunguje ten httpRequst, response a model zjistil tak, že jsem si nechal vypsat v šabloně nějaký string co jsem si zadal do basePresenteru pomocí beforeRender and this->template a ten string pak zkusil nahradit třeba $this->httpRequest->getRemoteAddress() a nevypsalo to nic.
Pokud to všechno předávám v normálním presenteru, tak všechno funguje.
Přes control jí vykresluji a protected jsem zkoušel také nastavit a nic.
Továrničku používám takovouto:
<?php
protected function createComponentPoll()
{
$control = new pollControl();
$control->setQuestionId(2);
$control->setHttpRequest($this->httpRequest);
$control->setHttpResponse($this->httpResponse);
$control->inject($this->model);
return $control;
}
?>
Ale jak jsem psal komponenta funguje normálně, akorát nevím jak jí předat ty věci jinak než extra z každého presenteru.
- Filip Procházka
- Moderator | 4668
Http\Request
a Http\Response
jsou
přístupné v presenteru by default
class FooPresenter extends BasePresenter
{
private $polls;
private $questionId;
public function injectPoll(MyApp\Polls $polls)
{
$this->polls = $polls;
}
public function actionDefault($pageId)
{
// tohle jsem si vymyslel, doplň vlastní logiku
$this->questionId = $this->polls->findPagePoll($pageId);
}
protected function createComponentPoll()
{
$control = new PollControl($this->polls);
$control->setQuestionId($this->questionId);
// nechápu na co tohle potřebuješ, ale budiž
$control->setHttpRequest($this->getHttpRequest());
$control->setHttpResponse($this->getHttpResponse());
return $control;
}
}
class PollControl extends Nette\Application\UI\Control
{
private $polls;
public function __construct(MyApp\Polls $polls)
{
parent::__construct();
$this->polls = $polls;
}
// ...
}
Editoval HosipLan (15. 10. 2012 17:57)
- Siam
- Člen | 54
HosipLan:
díky za odpověď. S tím upozorněním na to, že jsou ty dvě služby
default jsi mi dost pomohl. :)
Ten request a response tam chci kvůli zjištění IP adresy a práci s cookies. A pochopil jsem to tak, že je lepší to tam předat nějakým seterem z venku, než si to tahat z nějakého globálního prostoru. Pochopil jsem to blbě? Nebo ti jde o to, že práce s IP a cookies patří do modelu? On s nima vlastně pracuje model, ale protože jsem nevěděl jak zprovoznit v modelu ten request a response, tak jsem to předal z presenteru do komponenty a z komponenty do modelu, což je asi hodně špatné, ale nevěděl jsem jak to tam jinak zprovoznit.
- Filip Procházka
- Moderator | 4668
Práce se sušenkama do komponent a presenterů určitě patří. Ale v modelu může být také, pokud je to vhodné :) A tady to docela vhodné je.
A pochopil jsem to tak, že je lepší to tam předat nějakým seterem z venku, než si to tahat z nějakého globálního prostoru.
To je velice správně!
On s nima vlastně pracuje model, ale protože jsem nevěděl jak zprovoznit v modelu ten request a response, tak jsem to předal z presenteru do komponenty a z komponenty do modelu.
To už tak super není. Měl by sis je vyžadovat v konstruktoru
class Polls extends Nette\Object
{
private $httpRequest;
private $httpResponse;
private $db;
public function __construct(
Nette\Database\Connection $db,
Nette\Http\Request $httpRequest,
Nette\Http\Response $httpResponse)
{
$this->db = $db;
$this->httpRequest = $httpRequest;
$this->httpResponse = $httpResponse;
}
// nejake tvoje metody
}
Nette pak samo koukne do konstruktoru a uvidí, že vyžaduješ tyhle 3 třídy. Takže pokud budou registrované jako služby, tak ti je tam předá automaticky. Což nejspíš jsou.
services:
polls: Polls # nazev sluzby dvojtecka nazev tridy
Presenter a komponenta se nám pak zjednodušší
class FooPresenter extends BasePresenter
{
private $polls;
private $questionId;
public function injectPoll(MyApp\Polls $polls)
{
$this->polls = $polls;
}
public function actionDefault($pageId)
{
// tohle jsem si vymyslel, doplň vlastní logiku
$this->questionId = $this->polls->findPagePoll($pageId);
}
protected function createComponentPoll()
{
$control = new PollControl($this->polls);
$control->setQuestionId($this->questionId);
return $control;
}
}
class PollControl extends Nette\Application\UI\Control
{
private $polls;
public function __construct(MyApp\Polls $polls)
{
parent::__construct();
$this->polls = $polls;
}
// settery už nepotřebuješ
// render a signály
}
Editoval HosipLan (16. 10. 2012 11:23)
- Siam
- Člen | 54
Díky moc Filipe, zkusím se s tím nějak poprat a předělat to.
Nemůžeš mi prosím tě ještě poradit v tomto zapomenutém tématu?
- Siam
- Člen | 54
HosipLan:
udělal jsem to jak si psal (ještě jsem přidal do třídy polls namespace
MyApp) a při renderu v komponentě mi to vyhazuje laděnku „cannot read an
undeclared property MyApp\Polls::$httpRequest.“.
Ten httpRequest jsem volal v té komponentě jako $this->polls->httpRequest->getCookie… To, je správně, že? Nevíš v čem by mohla být chyba?
- Filip Procházka
- Moderator | 4668
Pokud tam máš private
, tak se k tomu dostaneš pouze zevnitř
třídy. Raději bych to co si hraje s těmi sušenkami nějak osekal/rozpůlil
a udělal si metodu v Polls
.
- Siam
- Člen | 54
HosipLan:
Už mi to jde, jupí. Měl jsem bordel v názvech proměnných, moje blbost.
Díky moc za pomoc!
Chtěl bych nějak zabránit aby nehlasovali boti a napadlo mě, že bych povolil hlasování jenom lidem co mají zapnuté cookies. Nepřišel jsem ale na to, jak ověřit, jestli to mají zapnuté, nebo ne. SetCookie vypadá, že false v případě neúspěchu nevrací a nevím, proč, ale nešlo mi ani zapsání cookies a pokus o jeho načtení s tím, že když se to podaří, vrátí to TRUE a to povolí v další metodě zápis do DB.
Existuje v nette nějaký elegantní způsob jak zjistit podporu těch cookie? Případně jiné řešení detekce botů?
- Tomas P
- Člen | 27
Aby som teda zhrnul (a uistil sa ze to chapem spravne) https://forum.nette.org/…sepresenteru#…
Ma to byt takto (obecne)?:
presenter P
zavislosti na service-och sa riesia same (rovnako ako o konstrukciu presenteru
sa stara nette)
staci vytvorit injectMyService(type param) a to sa zavola. V pripade
ze existuje len jeden service toho typu a je zapnuty (default = true)
autowire.
control C
konstrukciu aj zavislosti na service-och si riesime sami
instancia sa vytvori v P v metode
createComponentC(), kde spravime c = new C(…); a
c->set*()
na vlozenie service-ov, je ako pises idealne pouzit __construct(type1 service1,
type2 service2, …)
IMHO ja som to doteraz robil rovnako ako v presenteroch (s inject* metodami),
len som si to zavolal sam. To napr nechapem, preco nerobi nette jednotne, napr
parent construktor by kludne mohol zavolat inject*() metody.
model M
konstrukciu riesi nette a autowiring
vsetky dependencie sa predavaju v __construct
dedi od Nette\Object
Otazka
Niekde som cital (na fore ale neviem kde), ze na controloch by sa nemali menit
parametre konstruktoru – je to uz teraz neaktualne? resp. nemoze sa stat ze
bude nieco chciet system, ze instanciu vytvori sam? (predok PresenterComponent
napr. ma parametre)