Dostání proměnné do componenty header
- unjustolaf
- Člen | 29
Dobrý den,
Začel jsem v nette frameworku tvořit svůj první e-shop, s mnoha problémy jsem se už popral a dokázal je vyřešit ale tento ne.
Mám vytvořený header.latte ve složce templates/Components, který automaticky renderuji na začátek každé stránky v mém projektu pomocí {include „Components/header.latte“} v souboru layout.latte. Teď jsem se ale dostal do fáze kde bych potřeboval aby při každém načtení kterékoliv stránky v mém projektu se při zobrazovaní mého headeru (navbaru) v něm zobrazovala hodnota všeho zboží v košíku.
Vytvořil jsem si metodu která mi spočítá hodnotu všeho zboží v košíku daného uživatele a funguje bezchybně, můj opravdu jediný problém je, že nedokážu dostat výslednou hodnotu této metody do toho headeru (neboli templatu).
Takto vypadá moje metoda, která mi získá celkovou hodnotu zboží v košíku:
<?php
public function getTotalPrice()
{
$total_price_sum = 0;
$itemsInCart = $this->database->table("cart")->where("user_id", $this->user->getId())->fetchAll();
foreach ($itemsInCart as $item) {
$total_price_sum = $total_price_sum + ($item->item_price * $item->item_quantity);
}
return $total_price_sum;
}
?>
Takto vypadá můj marný pokus vytvořit Presenter ze kterého by daný header dostal proměnnou s názvem „cartTotal“:
<?php
class ComponentsPresenter extends BasePresenter
{
private $database;
private $cart;
public function __construct(Context $database, Cart $cart)
{
$this->database = $database;
$this->cart = $cart;
}
public function renderHeader()
{
$usersCart = $this->database->table("cart")->where("user_id", $this->getUser()->getId())->Count();
if ($usersCart !== NULL)
{
$cartTotal = $this->cart->getTotalPrice();
$this->template->cartTotal = $cartTotal;
}
}
?>
Zvláštní je, že když jdu na url /www/components/header tak se proměnná normálně načte ale ve chvíli kdy header loaduji přes layout.latte ji template nevidí.
Error = Undefined variable: cartTotal
Prosím pomožte mi, strávil jsem nad tímto již několik hodin a stále na
to nedokážu přijít.
Potřebuji vědět jak dostanu proměnnou do mé componenty header.latte kterou
zobrazuji na každé stránce?
S pozdravem,
unjustolaf
- MajklNajt
- Člen | 501
Ahoj, odporúčam v prvom rade poriadne preštudovať životný cyklus presenteru https://doc.nette.org/…n/presenters#… – renderNiečo vôbec neslúži na vykreslenie „časti“ stránky…
Ale ku konkrétnemu problému – ak chceš, aby sa ti nejaké premenné vkladali do šablóny pri každom requeste, musíš to dať do metódy beforeRender:
public function beforeRender()
{
parent::beforeRender()
$usersCart = $this->database->table("cart")->where("user_id", $this->getUser()->getId())->Count();
if ($usersCart !== NULL)
{
$cartTotal = $this->cart->getTotalPrice();
$this->template->cartTotal = $cartTotal;
}
}
Nie je to úplne ideálne riešenie, krajšie a použiteľnejšie by bolo spraviť si komponentu, ale na to časom prídeš sám :)
- unjustolaf
- Člen | 29
Ahoj, mockrát děkuji za ochotu pomoct mi s mým problémem. V nette frameworku dělám chvíli a neměl jsem moc od koho se jisté věci naučit a v dokumentaci se z vélké části ztrácím. Jistě si životní cyklus presenterů znovu prostuduji :).
Teď k mému problému, tvoje řešení jsem zkusil a bohužel mi vyskakuje pořád ten stejný error.
Když jdu na url: localhost:8888/e-shop/e-shop/www/components/header vše funguje jak má, proměnná je normálně přístupná.
Když ale jdu na jakoukoliv jinou stránku kde se automaticky renderuje header.latte z layout.latte, proměnná je stále nepřístupná.
Můj nynější kód v ComponentsPresenteru:
<?php
namespace App\Presenters;
use Nette;
use Nette\Database\Context;
use App\Model\Cart;
class ComponentsPresenter extends BasePresenter
{
private $database;
private $cart;
public function __construct(Context $database, Cart $cart)
{
$this->database = $database;
$this->cart = $cart;
}
public function beforeRender()
{
parent::beforeRender();
$usersCart = $this->database->table("cart")->where("user_id", $this->getUser()->getId())->Count();
if ($usersCart !== NULL)
{
$cartTotal = $this->cart->getTotalPrice();
$this->template->cartTotal = $cartTotal;
}
}
}
?>
- Ondřej Kubíček
- Člen | 494
protože určitě na jiné stránce načítáš jiný presenter, tak tu
metodu beforeRender
dej do BasePresenter
- unjustolaf
- Člen | 29
To jsem zkoušel už dávno, ale vždy mi vyskočí error při prohledávání databáze na řádku:
<?php
$usersCart = $this->database->table("cart")->where("user_id", $this->getUser()->getId())->Count();
?>
Error: Call to a member function table() on null
Přitom je to úplně stejný kód jako v ComponentsPresenteru
Celý kód BasePresenteru zde:
<?php
namespace App\Presenters;
use Nette;
use Nette\Database\Context;
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
private $database;
public function __construct(Context $database)
{
$this->database = $database;
}
public function beforeRender()
{
parent::beforeRender();
$user = $this->getUser();
if ($user->isLoggedIn())
{
$this->template->loggedin = $user->getIdentity();
$usersCart = $this->database->table("cart")->where("user_id", $this->getUser()->getId())->Count();
if ($usersCart !== NULL)
{
$cartTotal = $this->cart->getTotalPrice();
$this->template->cartTotal = $cartTotal;
}
}
}
}
?>
- Ondřej Kubíček
- Člen | 494
zkus si to tam předat přes @inject a constructor smaž
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
/** @var Context @inject */
public $database;
...
}
- unjustolaf
- Člen | 29
Ondřej Kubíček napsal(a):
zkus si to tam předat přes @inject a constructor smaž
abstract class BasePresenter extends Nette\Application\UI\Presenter { /** @var Context @inject */ public $database; ... }
Ondřeji i všem Vám ostatním mockrát děkuji za pomoct s mým problémem, toto řešení mi pomohlo.
Na závěr poslední otázka, abych si z tohohle něco taky odnesl. Když mám tento "@inject" v mém BasePresenteru, všechny ostatní Presentery už proměnnou $database vidí, nebo musím v každém presenteru kde pracuji s databází opět vytvořit tento inject nebo constructor ?
- Ondřej Kubíček
- Člen | 494
to už jsou základy php, takže public propery samozřejmě už podle názvu vidí jak potomci, tak ji můžeš volat i zvenku
- unjustolaf
- Člen | 29
Omlouvám se měl jsem tam někde překlep a nefungovalo mi to když jsem v tom daném presenteru odebral constructor tak jsem místo pořádného hledání chyby položil hloupou otázku.
Jen mě ještě zajímalo k čemu je v BasePresenteru tento řádek, nepřijde mi že by něco dělal.
<?php
parent::beforeRender();
?>
A ještě jednou děkuji. Nedokážeš si představit jak moc si mi pomohl.
- Pavel Kravčík
- Člen | 1196
@unjustolaf: Jestli používáš nějaké IDE (jestli ne – začni),
tak pomocí CTRL+levé myšítko
Tě to do té funkce odkáže a
můžeš se podívat co se tam děje. Zajistíš kontinuitu – tj. provede se
co je ve funkci rodiče a ty k tomu můžeš něco přidat, pokud tu metodu
přetěžuješ od rodiče.