Jak předávat model vnořeným komponentám
- newbie
- Člen | 31
Dejme tomu že mám tři komponenty.
BandListControl
AlbumListControl
TrackListControl
Jedna vypisuje kapely, druhá alba a třetí tracky
a každé k životu stačí jeden vlastní model:
BandRepository
AlbumRepository
TrackRepository
A teď jsem tak nějak pochopil jak použít jednu v komponentu v druhé, ale pokud chci v bandlistu vypsat alba a v nich jednotlivé tracky, tak jak to dělám teď, tak se mi to moc nelíbí. Teď bandlistu předám všechny tři modely(2 zbytečně), abych je mohl předávat dalším vnořeným komponentám.
Jak to dělám teď:
class BandListControl extends Nette\Application\UI\Control {
private $albumRepository;
private $bandRepository;
private $trackRepository;
private $displayAlbums = FALSE; // pokud chci ke každé kapele vypsat alba
public function __construct($selected, $albumRepository, $bandRepository, $trackRepository) {
parent::__construct();
$this->albumRepository = $albumRepository; // tohle tu mám jenom kvůli vnořené komponentě
$this->bandRepository = $bandRepository;
$this->trackRepository = $trackRepository; // tohle tu mám jenom kvůli vnořené komponentě ve vnořené komponentě
}
.
.
.
public function createComponentAlbumList(){
return new Multiplier(function ($name){
.
.
.
// zbytečné předávání trackRepository
return new AlbumListControl($selected, $this->albumRepository, $this->trackRepository);
});
}
}
BandList.latte
<div n:if="$displayAlbums"><b>Seznam alb:
{control "albumList2-$band->id"}
</div>
Jde komponentám nějak rozumněji předávat model? Kdybych měl v sobě 5 komponent a každá vypisovala data na základě rodiče, tak v té nejvyšší budu mít 4 zbytečné modely.
Editoval newbie (12. 3. 2013 6:14)
- David Matějka
- Moderator | 6445
pro kazdou komponentu si vytvor tovarnu, kterou registrujes jako sluzbu (v dev verzi muzes pouzit DI factories, ktery ti to zjednoduseji). priklad:
//BandListControlFactory.php
//tuhle factory si injectnej do presenteru a v createComponent metode das akorat return $this->bandListControlFactory->create();
class BandListControlFactory extends Object
{
protected $bandRepository;
protected $albumListControlFactory;
public function __construct(BandRepository $bandRepository, AlbumListControlFactory $albumListControlFactory)
{
....
}
public function create()
{
return new BandListControl($this->bandRepository, $this->albumListControlFactory);
}
}
//BandListControl.php
class BandListControl extends Control
{
protected $bandRepository;
protected $albumListControlFactory;
public function __construct(BandRepository $bandRepository, AlbumListControlFactory $albumListControlFactory)
{
....
}
public function createComponentAlbumList()
{
return new Multiplier($this->createAlbumListControl);
}
public function createAlbumListControl($name)
{
....
return $this->albumListControlFactory->create($selected);
}
}
//AlbumListControlFactory.php
class AlbumListControlFactory extends Object
{
protected $albumRepository;
protected $trackListControlFactory;
public function __construct(AlbumRepository $albumRepository, TrackListControlFactory $trackListControlFactory)
{
...
}
public function create($selected)
{
return new AlbumListControl($selected, $this->albumRepository, $this->trackListControlFactory);
}
}
a tak dal, cely to sem psat nebudu :) ten kod je pak mnohem lepe spravovatelnej, kdyz treba TrackListControl bude potrebovat dalsi zavislost, jen ji pridas do jeho factory
v neonu registrujes vsechny factory jako sluzby:
services:
bandListControlFactory: BandListControlFactory
.....
takhle ma kazda komponenta jen zavislosti na tom, co bude primo pouzivat, tzn. bandlistcontrol pouziva jen bandrepository a vytvari albumlistcontrol, o zavislosti albumlistcontrolu at se postara AlbumListControlFactory atd. :)
Editoval matej21 (12. 3. 2013 12:22)
- pawouk
- Člen | 172
Matej21 ti to napsal pěkně, jen doplním že jde o základní princip Dependency injection, tedy: nestarej se o závislosti, závislosti řeší někdo dříve. Tedy tak jak to píšeš ty prostě řešíš ty závislosti pozdě. Za druhé snaž se aby v tvém kódu bylo co nejméně slovo new. Vlastně by tam nemělo být vůbec. Výjimku tvoří Exception a třeba ArrayHash, to je defakto to samé jako array. Když si uvědomíš, že závislosti musíš řešit dříve mohl bys předávat hotové objekty a model do nich strčit už na začátku aplikace, ale to by bylo neefektivní, takže je lepší dělat továrny a tím je zjištěno že se vytvářejí až když jsou skutečně potřeba.
- ViPEr*CZ*
- Člen | 817
Filip Procházka napsal(a):
Tohle nepomohlo? :)
Si myslím, že na planette ty lidi ze začátku moc nechodí… spíš to
hledáš v dokumentaci jako takový, když se něco učíš. Navíc to je
návod pro 2.1-dev a někteří lidi prostě rádi slyší na něco jako stable,
i když spousta místních bere 2.1-dev jako samozřejmost.
(osobní názor)