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.