Komponenta, která zobrazuje menu (kategorie) – připojení do databáze
- Desttro
- Člen | 126
Zdravím,
udělal jsem si menu, které je propojeno s databází a vykresluje se do
šablony. Jenže jsem narazil na problém, že menu potřebuju na všech
stránkách, a nechci připojení furt definovat v Presenterech. Tak jsem
v dokumentaci narazil na komponenty.
Snažím se udělat jednoduchou komponentu, co v @layout.latte vykreslí
menu (seznam kategoríí).
Zde mám CategroyControl:
use Nette\Application\UI;
class CategoryControl extends UI\Control
{
private $database;
public function __construct(Nette\Database\Connection $database)
{
parent::__construct();
$this->database = $database;
}
public function render()
{
$template = $this->template;
$template->setFile(__DIR__ . '/CategoryControl.latte');
// vložíme do šablony nějaké parametry
$this->template->categories = $this->database->table('blog_categories');
// a vykreslíme ji
$template->render();
}
}
CategoryControl.latte
{snippet}
{foreach $categories as $category}
<li class="item-173"><a href="{$category->url}">{$category->title}</a></li>
{/foreach}
{/snippet}
Vždy mi to ale vyhodí chybu:
Recoverable Error
Argument 1 passed to CategoryControl::__construct() must be an instance of
Nette\Database\Connection, none given, called in
/home/psabrnak/web/domena.cz/public_html/app/FrontModule/presenters/HomepagePresenter.php
on line 20 and defined
Nevím si rady, co s tím. Ještě jsem se chtěk zeptat, zda musím vždy v presenterech vykreslovat komponentu – chci menu na všech stránkách, tak kde nejlépe umístit tento kód?
protected function createComponentCategory()
{
$category = new \CategoryControl;
return $category;
}
Děkuji moc za radu.
- David Matějka
- Moderator | 6445
Komponenta vyzaduje pripojeni, musis tam tedy pripojeni pridat. Pripadne si udelej tovarnicku a zkombinuj to (jestli chces) s autowired component factories :)
Editoval matej21 (20. 6. 2014 12:38)
- Desttro
- Člen | 126
Chápu to teda dobře, že musím udělat v app/components/ nový soubor IUserTableFactory.php, kde bude:
namespace App\Components;
interface ICategoryFactory
{
/**
* @return Category
*/
public function create();
}
- tím vytvořím rozhraní, poté bude moje komponenta propojená s databázi a ještě než spustím web, tak musím do configu napsat tohle?
services:
- App\Components\ICategoryFactory
Určitě to říkám špatně, že?
Editoval Desttro (20. 6. 2014 13:03)
- David Matějka
- Moderator | 6445
skoro dobre:)
jen ten soubor pojmenuj „ICategoryFactory.php“ a oprav si
@return
anotaci, aby to spravne odkazovalo na onu komponentu, tedy
\CategoryControl
(pripadne presun CategoryControl do namespace
App\Components
a pak staci CategoryControl
bez
zpetneho lomitka)
Ono nette dle toho rozhrani vytvori tovarnicku na tu komponentu a komponentu vytvori spravne se vsemi zavislostmi
- Desttro
- Člen | 126
Děkuji za radu, udělal jsem to, ale furt mi to vyhazuje chybu:
Recoverable Error
Argument 1 passed to CategoryControl::__construct() must be an instance of
Nette\Database\Connection, none given, called in
/home/psabrnak/web/maxsecure.cz/public_html/app/FrontModule/presenters/HomepagePresenter.php
on line 20 and defined
v @layout.latte mám: {control category}
ICategoryFactory.php:
namespace App\Components;
interface ICategoryFactory
{
/**
* @return \CategoryControl
*/
public function create();
}
v HomepagePresenter mám:
protected function createComponentCategory()
{
$category = new \CategoryControl;
return $category;
}
když to smažu., tak to křičí logicky, že:
Nette\InvalidArgumentException
Component with name ‚category‘ does not exist.
- David Matějka
- Moderator | 6445
tu factory musis vyuzit, viz posledni blok kodu v prvnim odkazu, pripadne druhy odkaz
- Desttro
- Člen | 126
Vypadá to, že to funguje, ale ještě mi to hlásí chybu:
Nette\MemberAccessException
Call to undefined method Nette\Database\Connection::table().
zde je ten CategoryControl
use Nette\Application\UI;
class CategoryControl extends UI\Control
{
private $database;
public function __construct(Nette\Database\Connection $database)
{
parent::__construct();
$this->database = $database;
}
public function render()
{
$template = $this->template;
$template->setFile(__DIR__ . '/CategoryControl.latte');
// vložíme do šablony nějaké parametry
$this->template->categories = $this->database->table('blog_categories');
// a vykreslíme ji
$template->render();
}
}
- stewestw
- Člen | 42
ahojte,
neviete mi prosim poradit, kde robim chybu s DI?
<?php
use Nette\Application\UI\Control;
class MenuControl extends Control
{
/** @var Nette\Database\Context */
public $user;
private $database;
public function __construct(Nette\Database\Context $database)
{
parent::__construct();
$this->database = $database;
}
public function render()
{
$template = $this->template;
$menuItems = $this->database->table('nette_menu');
$itms = array();
if(count($menuItems) > 0){
foreach($menuItems as $item){
$itmsLink = ":Admin:".((trim($item->module) !== "") ? $item->module.":" : "").((trim($item->presenter) !== "") ? $item->presenter.":" : $item->module).((trim($item->action) !== "") ? $item->action : "") ;
$itms[] = array("link" => $itmsLink, "title" => $item->title);
}
}
$this->template->menuItems = $itms;
$template->render(__DIR__ . '/MenuControl.latte');
}
}
stale mi to hadze chybu:
Argument 1 passed to MenuControl::__construct() must be an instance of Nette\Database\Context, none given, called in /Applications/XAMPP/xamppfiles/htdocs/custom_cms/app/presenters/BaseAdminPresenter.php on line 12 and defined
a to som siel presne podla vaseho navodu, co ste tu riesili :(
dakujem.
- stewestw
- Člen | 42
volam ju v AdminBasePresenteri takto:
<?php
namespace App\Presenters;
abstract class BaseAdminPresenter extends \App\Presenters\BasePresenter{
public $database;
protected function createComponentMenu()
{
$menu = new \MenuControl;
return $menu;
}
protected function startup()
{
parent::startup();
if (!$this->getUser()->isLoggedIn() && $this->name !== "Admin:Login:Login") {
//die($this->name);
$this->redirect(":Admin:Login:Login:default");
}
}
}
- Etch
- Člen | 403
$menu = new \MenuControl;
ti nikdy nemůže fungovat. Použij create:
interface MenuFactory{
/**
* @return \MenuControl
*/
public function create();
}
do presenteru přidej:
/** @var \MenuFactory @inject */
public $menuFactory;
protected function createComponentMenu(){
return $this->menuFactory->create();
}