Diskuze: Pripojenie komponenty k DB
Tvůrce
Zobrazeno 16 zpráv z 16.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
Ahoj, jednoduše si závislost na modelu předám pomocí DI.
Takze klasicky cez konstruktor ako v presenteri ?
<?php
/**
* Created by PhpStorm.
* User: Dominik Gavrecký
* Date: 22.05.2016
* Time: 19:26
*/
namespace Nette\Forms\Controls;
use Nette\Application\UI\Control;
use App\Model\NewsManager;
class Category extends Control
{
/** @var newsManager*/
public $newsManager;
/**
* Category constructor.
* @param newsManager $newsManager
*/
public function __construct(newsManager $newsManager)
{
parent::__construct();
$this->newsManager = $newsManager;
}
public function renderCategory($id){
$this->template->categoryName = $this->newsManager->getCategory()->where('id', $id);
$this->template->news = $this->newsManager->getNews();
$this->template->setFile(__DIR__ . '/name.latte');
$this->template->render();
}
}
Takto som to skúsil spraviť ale nabehne mi error.
Argument 1 passed to Nette\Forms\Controls\Category::__construct() must be an instance of App\Model\NewsManager, none given, called in /web/htdocs3/rewizeu/home/subdoms/dev/app/AdminModule/presenters/NewsPresenter.php on line 146
Ahoj, mám k tomu hned několik věcí.
// Podle tohoto namespace, se ta třída jmenuje "NewsManager".
use App\Model\NewsManager;
// Potom ale dodržuj ten správný název s velkými písmeny.
/** @var NewsManager*/
public $newsManager;
/**
* Category constructor.
* @param NewsManager $newsManager
*/
public function __construct(NewsManager $newsManager)
{
parent::__construct();
$this->newsManager = $newsManager;
}
Tohle si nejdříve vyřeš a potom se uvidí.
Teraz by to malo byť správne. Registrovaný aj správne napísaný ten namespace je presne rovnakým spôsobom ako sa ho snažím využiť v komponente ho využívam aj v presenteri s tým rozdielom že v presenteri mi to funguje.
<?php
/**
* Created by PhpStorm.
* User: Dominik Gavrecký
* Date: 22.05.2016
* Time: 19:26
*/
namespace Nette\Forms\Controls;
use Nette\Application\UI\Control;
use App\Model\NewsManager;
class Category extends Control
{
/** @var NewsManager */
public $newsManager;
/**
* Category constructor.
* @param NewsManager $newsManager
*/
public function __construct(NewsManager $newsManager)
{
parent::__construct();
$this->newsManager = $newsManager;
}
/**
* @param $id
* Render Category a jeho vykreslenie do name.latte
*/
public function renderCategory($id){
$this->template->categoryName = $this->newsManager->getCategory()->where('id', $id);
$this->template->news = $this->newsManager->getNews();
$this->template->setFile(__DIR__ . '/name.latte');
$this->template->render();
}
}
No, tak ještě jedna technická připomínka, které jsem si před tím nevšiml, ale také by neměla mít vliv na funkčnost...
// Ten atribut by měl být spíš private.
/** @var NewsManager */
private $newsManager;
A potom si promaž cache i log a podívej se, jestli to pořád hází tu samou chybu nebo třeba nějakou jinou?
A pokud je to ta samá, tak sem ještě pošli, jak inicializuješ tu komponentu Category v rámci presenteru, ve kterém ji používáš. Mám takový pocit, že chyba bude nejspíše tam.
Toto mám v presenteri s tým že som ten controler premenoval a cache som zmazal a namespace mám správny
protected function createComponentCategory()
{
$control= new NewsComponent;
return $control;
}
Pre istotu tu dám aj upravený controler
<?php
/**
* Created by PhpStorm.
* User: Dominik Gavrecký
* Date: 22.05.2016
* Time: 19:26
*/
namespace Nette\Forms\Controls;
use Nette\Application\UI\Control;
use App\Model\NewsManager;
class NewsComponent extends Control
{
/** @var NewsManager */
private $newsManager;
/**
* Category constructor.
* @param NewsManager $newsManager
*/
public function __construct(NewsManager $newsManager)
{
parent::__construct();
$this->newsManager = $newsManager;
}
/**
* @param $id
* Render Category a jeho vykreslenie do name.latte
*/
public function renderCategory($id){
$this->template->categoryName = $this->newsManager->getCategory()->where('id', $id);
$this->template->news = $this->newsManager->getNews();
$this->template->setFile(__DIR__ . '/name.latte');
$this->template->render();
}
}
Tak pak je to úplně jasné...
protected function createComponentCategory()
{
$control= new NewsComponent; // TOHLE JE ŠPATNĚ!*
return $control;
}
* Pokud totiž instanciuješ komponentu tímto způsobem, pomocí new, musíš se o předání závislostí v konstruktoru postarat sám. Druhým způsobem je pak používání továrniček, kde se o dodání závislostí stará Nette samo, pomocí DI. Tohle vše je popsané v mém seriálu o Nette.
Ako to myslis sám mohol by si mi poskytnúť nejaký názorný príklad ?
No dobrá, tak že jsi to ty.
// Uvnitř daného presenteru.
/** @var NewsManager */
private $newsManager;
/**
* Presenter constructor.
* @param NewsManager $newsManager
*/
public function __construct(NewsManager $newsManager)
{
parent::__construct();
$this->newsManager = $newsManager;
}
protected function createComponentCategory()
{
/* Předáváš závislost v konstruktoru,
přičemž tu předávanou instanci musíš samozřejmě někde získat,
v tomto případě pomocí DI v rámci daného presenteru. */
$control= new NewsComponent($this->newsManager);
return $control;
}
// Uvnitř souboru s třídou komponenty *Category* přidáme ještě interface.
class Category extends Control
{
...
}
interface ICategoryFactory
{
/**
*
* @return Category
*/
public function create();
}
// Ten pak musíme zaregistrovat jako službu továrničky v konfiguračním souboru.
services:
- Nette\Forms\Controls\ICategoryFactory
// A dále tuto továrničku získáme v presenteru pomocí DI a použijeme pro tvorbu komponenty.
// Uvnitř daného presenteru.
/** @var ICategoryFactory */
private $categoryFactory;
/**
* Presenter constructor.
* @param ICategoryFactory $categoryFactory
*/
public function __construct(ICategoryFactory $categoryFactory)
{
parent::__construct();
$this->categoryFactory = $categoryFactory;
}
protected function createComponentCategory()
{
// Instance se prostě vytvoří a o všechny její závislosti je postaráno automaticky.
$control= $this->categoryFactory->create();
return $control;
}
Tak si myslím, že víc názornější už jsem snad být nemohl. Máš k tomu ještě nějaké otázky?
Ďakujem ti vážne si to od teba strašne vážim
Dodal bych jen takové detaily. Pro vlastní komponenty nepoužívej namespace Nette\Forms\Controls ale nejaky vlastní, tohle platí pro všechny třídy. Proste to nedává smysl, jelikož ta tvoje komponenta neni součásti Nette dále v konstruktoru potomka UI\Control neni potřeba volat předkuv kontruktor, jelikož by mel byt volný.
Zobrazeno 16 zpráv z 16.