Ako preniest do komponenty model, popripade dalsiu sluzbu
- duskohu
- Člen | 778
Zdravim, viete mi poradit? Ako viem preniest do komponenty model alebo nejaku spuzbu bez predavania v tovarnicke presenteru? Problem je v tom ze ked sa to snazim pridat do neonu ako:
userFormControl: UserFormControl(@users)
tak to neprejde lebo mi stale da na zaciatok:
$control = new \UserFormControl($this, $name);
Presenter
protected function createComponentEditUser($name) {
$control = new \UserFormControl($this, $name);
return $control;
}
Komponenta
class UserFormControl extends BaseFormControl {
// a sem by som potreboval dostat
//\Nette\Mail\SmtpMailer
// Users
}
Neon
common:
parameters:
smtp:
smtp: true
host: 'smtp-....'
username: 'admin@....'
password: '......'
secure: 'ssl'
nette:
mailer: %smtp%
services:
users: Users
- David Ďurika
- Člen | 328
neon
services:
favoritePanelComponent: Components\Front\FavoritePanel
prezenter
<?php
/**
* @return \Components\Front\FavoritePanel
*/
protected function createComponentFavoritePanel()
{
return $this->getService('favoritePanelComponent');
}
?>
componenta
<?php
class FavoritePanel extends Components\BaseControl {
protected $favorite;
protected $favoritesLists;
public function __construct(Models\Favorite $favorite, Models\FavoritesLists $favoritesLists) {
list($this->favorite, $this->favoritesLists) = func_get_args();
parent::__construct();
}
}
?>
do somponenty nepredavaj $this a $name staci ak pouzijes tovarnicku
- studna
- Člen | 181
Ono když už máš tu komponentu jako službu v kontejneru, tak je na tobě, jestli použiješ ->getService a nebo inject* metodu v presenteru.
Použití kontextu je podle mě na místě, protože na službu/komponentu sáhneš až tehdy, kdy ji skutečně potřebuješ.
Editoval studna (16. 11. 2012 18:31)
- leninzprahy
- Člen | 150
Já jsem si v BasePresenter
u přetížil
createComponent()
asi takto
/** @var \Nette\DI\Container */
private $container;
/**
* @param \Nette\DI\Container $container
*/
public function injectContainer(\Nette\DI\Container $container)
{
$this->container = $container;
}
/**
* Component factory.
*
* @param string component name
* @return IComponent the created component (optionally)
*/
public function createComponent($name) {
$component = parent::createComponent($name);
foreach (array_reverse(get_class_methods($component)) as $method) {
if (substr($method, 0, 6) === 'inject') {
$this->container->callMethod(array($component, $method));
}
}
return $component;
}
a v komponentě pak jde normálně používat (za předpokladu že komponentu vytváříš továrničkou)
class UserFormControl extends BaseFormControl {
// a sem by som potreboval dostat
//\Nette\Mail\SmtpMailer
// Users
/** @var Namespace\User */
private $user;
/** @var Nette\Mail\SmtpMailer */
private $mailer;
public function injectUser(Namespace\User $user)
{
$this->user = $user;
}
public function injectMailer(Nette\Mail\SmtpMailer $mailer)
{
$this->mailer = $mailer;
}
}
Editoval leninzprahy (16. 11. 2012 19:01)
- David Ďurika
- Člen | 328
@enumag: to bol len priklad snazim sa dodrziavat to ze nepouzivam context ani getService(), ale to co vravel @studna je tiez pravda…
@leninzprahy super napad!
- David Ďurika
- Člen | 328
@enumag bud si v prezentry injectnes tu componentu ale potom to uz nebude tak lazy… alebo si spravis factory na tu componentu, tym padom injectujes len factory a samotna componenta sa vytvory az v monente ked ju naozaj potrebujes…
- David Ďurika
- Člen | 328
@enumag az na to ze potom prides o lazy load tej componenty, v tom priklade co uvadza @leninzprahy je komponenta injectovana a inicializovana stale ked sa zavola prezenter… coz je zbytocne…
- enumag
- Člen | 2118
@achtan: Myslím, že sis špatně prohlédl ten zdroják. Do presenteru injectuje @container (což mi připadá zbytečné), ne komponentu.
Ve výsledku chci použít akorát tohle:
/**
* Component factory.
*
* @param string component name
* @return IComponent the created component (optionally)
*/
public function createComponent($name) {
$component = parent::createComponent($name);
$this->context->callInjects($component); //vyžaduje Nette 2.1
return $component;
}
- leninzprahy
- Člen | 150
Je fakt že se tam ten container injektuje zbytečně, protože už tam je jako context…
v Base presenter
u by to pak mohlo vypadat
/**
* Component factory.
*
* @param string component name
* @return IComponent the created component (optionally)
*/
public function createComponent($name) {
$component = parent::createComponent($name);
foreach (array_reverse(get_class_methods($component)) as $method) {
if (substr($method, 0, 6) === 'inject') {
$this->context->callMethod(array($component, $method));
}
}
return $component;
}
Jinak context->callInjects(...);
vypadá dobře, po přechodu
na 2.1 si to určitě upravím
- enumag
- Člen | 2118
Má původní verze pro Nette 2.1 obsahuje bug, takže kdyby to někdo hledal tak takhle:
/**
* Component factory.
*
* @param string $name
* @return IComponent
*/
protected function createComponent($name)
{
$component = parent::createComponent($name);
if ($component) {
$this->getContext()->callInjects($component);
}
return $component;
}