Tvorba tovarnicky na komponentu
- marcelxy
- Člen | 70
Prosim o radu snazim se vytvorit samostatnou komponentu kterou muzu pouzit
opakovane na ruznych mistech potrebuji vni pracovat s db pridavat mazat atd
takze tam potrebuji pripojeni k db absolutne jednoducha a primitivni vec! a je
to pro me uz treti den absolutne neprekonatelny problem! procet jsem uplne vse
od quiqstartu dokumentaci az po fora a DI nechapu! takze sem se snazil
postupovat standartne, komponenta funguje bez problemu mam pro ni vytvorenou
specialni sablonu kterou bezproblemu nacte kdyz tu komponentu zavolam pres
{control …} ale v momente kdyz potrebuji pracovat s db nemam pripojeni a
nejsem schopen ho v te komponente vytvorit ani ho tam predat!
V presenteru mi pripojeni v pohode funguje ale v komponente kterou vytvarim
jako instanci v danem presenteru uz ne!
Kdyz se snazim vytvori interface a factory coz uz vubec nechapu proc a kcemu to
je? a sluzbu v konfigu tak mi to zas neni schopno nacis sablonu ze pry
„Interface function App\kontaktformFactory::render() cannot contain body“
prosim je nejaka jednoducha cesta jek ziskat pripojeni k db tam kde ho
potrebuji napr. v te samostatne komponente? Moc diky za rady a prosim
neodkazovat na quiqstart dokumentaci a podobne… procet se to xkrat ale proste
mi to ztoho neni jasne!!je to delane pro odborniky ne pro zacatecniky!diky za
pochopeni! pouzivam nette 2.1
Editoval marcelxy (5. 1. 2014 15:01)
- Šaman
- Člen | 2666
Huh, to bude na dýl. Je to trochu komplexní téma.
- Pro úplný začátek si můžeš vytáhnout databázi z presenteru
(připojená komponenta má k němu přístup přes
$this->presenter
). Je to ale špatně a budeš to muset zrefaktorovat! Musíš ale někde začít a pokud tu komponentu rozchodíš takto, tak je na čem stavét dál. - Vytvoříš si tovární třídu, která si injectuje databázi a jiné závislosti a umí vytvořit a nakonfigurovat konkrétní instance tvé komponenty.
- Tohle jde zautomatizovat pomocí generovaných továren. Ty se ale mezi verzemi @dev a @final trochu změnily, tak si jdu zaktualizovat příklad a někam ho nasdílím.
P.S. Připojená komponenta znamená, že presenter nemáš k dispozici už
v konstruktoru, ale nejdříve v metodě attach()
. V
render()
už je připojená určitě.
Editoval Šaman (4. 1. 2014 9:53)
- marcelxy
- Člen | 70
Aha
1. tak sem postupoval, ze jsem se v komponente snazil vytvorit pripojeni jak v presenteru
private $conect;
public function __construct(\Nette\Database\Context $conect)
{
$this->conect = $conect;
}
a pak uz jen $this->conect->table(‚kontakty‘)->insert($values);
coz v presenteru normalne funguje ale v komponente uz ne, hlasi
to „__construct() must be an instance of Nette\Database\Context, none given“
z cehoz mi plyne ze mu musim predat to pripojeni k db ale nevim jak? kdyz tu
instanci te komponenty vytvarim v presenteru kde mi pripojeni k db funguje tak
jak jsem uved na zacatku! takze v presenteru jsem mel!
public function createComponentContaktForm()
{
$frmkot = new kontaktform(a tady si myslim ze bych mel predat pripojeni k db?);
return $frmkot;
}
ale nevim jak ,ale asi to neni ani spravne ten system je tvoren asi jinak a to pres DI coz nechapu!
2. pak mi nekdo na foru poradil ze mam jit pres interface a factory coz taky
dost dobre nechapu!
takze jsem prejmenova z class mjetrida na
namespace App;
interface FooFactory
{
tady jsem dal kod te me komponenty stejne jako driv ve class{...}
/**
* @return Foo
*/
public function create();
}
a v presenteru ji pak volam pres
public $fooFactory;
public function createComponentFoo()
{
$foo = $this->fooFactory->create();
return $foo;
}
}
a to mi vyhazuje ze
"Interface function App\kontaktformFactory::render() cannot contain body“
z cehoz mi plyne ze tento postup nemuze pracovat s sablonou? kterou ovsem ta
komponeta potrebuje!
takze to delam asi taky spatne?
Takze ted nevim kde co pridat nebo ubrat?
A uz vubec nechapu kdyz v dokumentaci se pise ze
"Narovinu: Dependency Injection (DI) není nic tajemného nebo
nepochopitelného. Celé se dá shrnout do jedné sobecké věty: „nic
nesháněj, ať se postará někdo jiný.“ Nic víc, nic míň.
tak musim byt asi menecenej! ze tri dny nejsem schopen se hnout z mista a to pripojeni k db te komponente predat nebo ji v ni vytvorit! i kdyz samostatna kom. mi bez pripojeni k db. normalne funguje!
Editoval marcelxy (4. 1. 2014 10:54)
- Jan Tvrdík
- Nette guru | 2595
A uz vubec nechapu kdyz v dokumentaci se pise ze "Narovinu: Dependency Injection (DI) není nic tajemného nebo nepochopitelného. Celé se dá shrnout do jedné sobecké věty: „nic nesháněj, ať se postará někdo jiný.“ Nic víc, nic míň.
tak musim byt asi menecenej! ze tri dny nejsem schopen se hnout z mista a to pripojeni k db te komponente predat nebo ji v ni vytvorit!
Problém je, že na řádku $frmkot = new kontaktform(...);
jsi
porušil to pravidlo, že nemáš nic shánět. Ty sháníš připojení
k databázi a divíš se, že ten koncept dobře nefunguje, když
nerespektuješ jeho pravidla.
Navíc „Interface function App\kontaktformFactory::render() cannot contain body“ znační, že máš nedostatky v základech PHP, konkrétně v tom k čemu slouží a jak fungují rozhraní.
- marcelxy
- Člen | 70
Jo to mas asi pravdu ucim se postupne!ale jsem strasne rad ze odpovidas ty! poslouchal jsem tvou prednasku o komponentach v planette asi 20× je super!!!!! ale tu cast kde prave resis to pripojeni k db jako samostatnou vrstvu kterou sis vytvoril doma tak to sem proste nepochopil jak si to tam presne dostal to pripojeni k db a v tom mam ten problem!!!ale jinak mas samozdrejme pravdu nedostatky mam jeste velke jsem zacatecnik ale myslim si ze bych ten prooblem mel umet prekonat ze svymi znalostmi!!
- marcelxy
- Člen | 70
No ja to pripojeni neshanim ja kdyz ho tam nadam coz byl muj puvodni zamer
protoze jsem si myslel ze si ho injektuje sam, tak mi tvrdi
„__construct() must be an instance of Nette\Database\Context, none given“ to
znamena presne co? ze po me chce to pripojeni?
myslel jsem si ze bych mu ho mohl nejak predat!ale to asi nejde! ze?
- Jan Tvrdík
- Nette guru | 2595
„__construct() must be an instance of Nette\Database\Context, none given“ to znamena presne co?
Absenci tvých základů PHP. Je to standardní chybová hláška PHP, která tě informuje, že nerespektuješ typehint konstruktoru.
- Jiří Nápravník
- Člen | 710
Doproučuji opravdu ten článek, co poslal Honza.
Či-li pak zjistíš, že by to mělo být nějak takhle.
interface:
namespace App;
interface FooFactory
{
/**
* @return Foo
*/
public function create();
}
žádné tělo, jen prostě definuješ předpis, jak to má vypadat.
Samotná komponenta:
namespace App;
class Foo
{
private $connect;
public function __construct(\Nette\Database\Context $connect)
{
$this->connect = $connect;
}
}
do config.neon:
services:
- App\FooFactory
No a ted ot musíš dostat do presenteru. V 2.1 je nejlepší asi takto:
class NejakyPresenter extends BasePresenter
{
/**
* @var \App\FooFactory
* @inject
*/
public $fooFactory;
public function createComponentFoo()
{
$foo = $this->fooFactory->create();
return $foo;
}
}
tím se ti předá samo připojení k databázi, protože to pozná nette podle toho rozhraní co jsi uvedl v konstruktoru komponenty.
Editoval Jan Tvrdík (4. 1. 2014 14:45)
- marcelxy
- Člen | 70
Je panove ja vam vsem moc dekuji za trpelivost! ja to konecne rozjel! Ja vim
ze me znalosti jsou chatrne ale ja vubec netusil ze ty „komentare“ jsou pro
beh celeho systemu nepostradatelne!!! Ja uz jsem to chtel vzdat kdyz sem si
najednou vsimnul ze ty komentare neboli anotace ovlivnuji colou funkcnost! pak
kdyz jsem je tam vsechny spravne vlozil najednou se to rozjelo! ale bez nich to
nejede!! to kdybych vedel tak si usetrim 3 dny trhani vlasu!!
Prosim o posledni vec jestli nekde se o vyznamu a pouziti tech anotaci pise
podrobne? krome jednoho odstavce sem k tomu nic moc nenasel potrebuji to
dostudovat!! Diky za odpoved a vsem za trpelivost.
- Myiyk
- Člen | 321
Nějaké info o anotacích podrobně jsem neviděl. V nette jsem viděl jen anotace @inject a @var <typ>. Další anotace jsou pro dokumentaci (@var je taky dokumentační, ale nette ho používá).
Základní anotace na wikipedii https://en.wikipedia.org/wiki/PHPDoc#Tags
- David Matějka
- Moderator | 6445
@marcelxy: z hlavy me napada par anotaci, co nette vyuziva a mohou
ovlivnovat chod programu:
@inject
anotace pro doplnovani zavislosti – co ma doplnit hleda v anotaci
@var
@return
u generovanych tovarnicek
@persistent
anotace u persistentnich parametru
@persistent
anotace u persistentnich komponent
@User(loggedIn) v presenterech pro autorizaci, v doc nevim, kde to je,
v kodu zde
@method
pro magicke metody
Editoval matej21 (5. 1. 2014 0:13)
- marcelxy
- Člen | 70
Aha tak dik ja si tu 3 dny rvu vlasy jak udelat DI inject na databazi a
nakonec se dozvim ze mam problem v anotaci no to je vyborne! bez te anotace ten
inject nejede ze? To tam musi byt * @inject
i ta cesta k te sluzbe * @var \App\KontaktFormFactory taky,
Jinak ten inject nepojede ze ?? Jinak diky vsem za trpelivost
- David Matějka
- Moderator | 6445
inject anotace je jen jedna z moznosti, jak dostat zavislosti do presenteru, dale muzes vyuzit klasicky konstruktor injection
class FooPresenter extends BasePresenter
{
protected $bar;
public function __construct(Bar $bar)
{
$this->bar = $bar;
}
}
nebo inject* metody – kazda metoda, ktera zacina na inject* se zavola s prislusnyma zavislostma
class FooPresenter extends BasePresenter
{
protected $bar;
public function injectBar(Bar $bar)
{
$this->bar = $bar;
}
}
u tohoto zpusobu injectovani zavislosti (jak konstruktor, tak inject metody) nejsou dulezite anotace, ale typehint v argumentech metody.
konstruktor injection je vsak v presenterech pouzitelny malokdy, na druhou stranu, ve sluzbach a komponentach preferuj konstruktor injection a jiny zpusob pouzivej jen v krajni nouzi
pro presentery je v soucasnosti „preferovanym“ zpusobem pouziti @inject anotaci