Komponenta vytvářená továrničkou nevrací instaci komponenty
- Oli
- Člen | 1215
Ahoj,
mám chybovou hlášku:
Nette\UnexpectedValueException
Method FrontendModule\PagesPresenter::createComponentBox() did not return or create the desired component.
Vím co to znamená, ale nevím jak to opravit. S neonem zatím nejsem
nejlepší kamarád.
Když vytvářím komponentu konstruktorem, tak to jde:
public function createComponentBox()
{
return new \Box($this->pageModel);
}
Když ji ale chci vytvořit továrničkou, tak to nejde. Postupoval jsem (doufám) přesně podle Vícenásobné použití formuláře: dědičnost nebo továrna?, ale hází mi to tu chybu.
presenter:
public $box;
public function __construct(\Box $box)
{
$this->box = $box;
}
public function createComponentBox()
{
return $this->box->action();
}
neon:
services:
box: Box
Box:
use Nette\Application\UI\Control;
class Box extends Control
{
private $db;
private $box;
public function __construct(Nette\Database\Connection $db)
{
$this->db = $db;
}
public function action()
{
$this->box = 'ahoj';
}
public function render()
{
$this->template->box = $this->box;
$this->template->setFile(dirname(__FILE__) . '/template.latte');
$this->template->render();
}
}
Otázka teda zní, proč to nevytváří komponentu?
Díky
- Vojtěch Dobeš
- Gold Partner | 1316
Protože v té továrničce vracíš výsledek metody action()
,
což je řetězec 'ahoj'
. Vracej pouze tu komponentu.
- David Matějka
- Moderator | 6445
jinak, to pouziti neni spravne. komponenta by nemela byt registrovana jako sluzba, mel bys mit registrovanou pouze tovarnu na komponentu, s DI factories se to zjednodusuje, bez nich je to o par radku slozitejsi, ale fakt jen o par :)
1. pri obojim budes mit componentu jako mas ted:
class Box extends Control
{
public function __construct(NejakaZavislost $foo)
{
....
}
...
}
2a. pokud pouzijes DI factories , tak napises tohle interface
interface BoxFactory
{
public function create();
}
a do configu:
factories:
boxFactory:
class: Box
implement: BoxFactory
2b. pokud nepouzijes DI factories, tak musis tovarnu napsat rucne
class BoxFactory extends Nette\Object
{
protected $foo;
public function __construct(NejakaZavislost $foo)
{
$this->foo = $foo;
}
public function create()
{
return new Box($this->foo);
}
}
a registrujes tovarnu jako sluzbu:
services:
boxFactory: BoxFactory
3. pouziti v presenteru je pak stejne
class BarPresenter extends BasePresenter
{
protected $boxFactory;
public function __construct(BoxFactory $boxFactory)
{
$this->boxFactory = $boxFactory;
}
public function createComponentBox()
{
return $this->boxFactory->create();
}
}
factory muzes samozrejme injectnout i pres inject* metody, @autowire nebo nejlepe injectnutim primo do createComponent* metody
takhle muzes pouzit „Box“ ve více komponentách (respektive createComponent* metodach), v tvem reseni by to byla vsude stejna instance…