ublaboo/presenter-component: Jednodušší tvorba továrniček komponent pomocí anotací
- Pavel Janda
- Člen | 977
Ne vůbec ne. :)
Jde jen o zavolání metody pojmenované v anotaci, nemusí se to psát
„zdlouhavě“. Ale například v administraci to dokáže slušně
zpřehlednit Presenter.
Je to pár řádků. Kdyby to někdo použil a chtěl třeba něco přidat, nemám problém.
- greeny
- Člen | 405
Náročnost psaní kódu je ± stejná, napíšu řádek pro každou akci (navěšení callbacku, zavolání create metody, …), ale tvým řešením přijdu o napovídání IDE a jeho funkce jako Find Usages nebo Refactor. Navíc ve složitějších aplikacích jsou ty továrničky víc custom (například většina mých továrniček na formuláře příjmá v create metodě entitu, kterou upravuju, a předá ji do Formu). Což přes tvou knihovnu neudělám.
Jinak to ale není špatný nápad a chválím hlavně testy.
- Pavel Janda
- Člen | 977
@greeny
1, Ano, taky si všude posílám entity. :) create
metodě můžeš
jakýkoliv parametr poslat anotací @componentArgs
,
například tedy:
/**
* @var Shop\Product
*/
public $product;
/**
* @var App\Forms\ProductFormFactory
* @inject
* @component productForm:create
* @componentArgs product
*/
public $productFormFactory;
Do metody create
Továrny ProductFormFactory
ti
přijde produkt, který tam naplníš třeba v Action metodě presenteru (ani
to nemusí být presenter, dá se to použít v jakékoliv třídě, která
extendí PresenterComponent).
2, S tím IDE souhlasím. Na druhou stranu, já zůstávám používat Sublime, IDE je pro mě moc pomalé. Takže to pardon. :)
Dík za comment.
- enumag
- Člen | 2118
Hmm nápad to není špatný, ale komponenty pomocí Kdyby/Autowired se mi líbí více. A hlavně když už anotace tak Kdyby/Annotations. :-)
- Pavel Janda
- Člen | 977
Částečně souhlasím.
Ale přeci pokud mám jednoduchý problém (nechci stále psát továrničky, chci to dát do anotace) a potřebuji ho vyřešit na projektech menší až střední velikosti, sáhnu radši po řešení, které má všehovšudy 120 řádků, je naprosto průhledné, čitelné a lehce testovatelné.
Pokud bych potřeboval širší funkcionalitu, určitě bych zvažoval i širší řešení.
Pozor! Nerad bych vedl k názoru, že věci bastlím do jednoho souboru na
co možná nejméně řádků. Jen v lecčems třeba nevidím takovou
složitost.
Třeba jsem narazil na některé z balíku Webchemistry. Některé se mi
líbily, jmenovitě třeba Images Storage. Po čase jsem si napsal totéž,
protože mi nedávalo smysl, aby takové jednoduché rozšíření mělo mít
40 tříd. Totéž, akorát dvakrát rychlejší, dvakrát chytřejší a
8× menší.
Ze stejného důvodu nechápu, proč má aplikace, kterou vytvořím během 5 minut u tutorialu Symfony, 70MB. Kdo se s tím má nahrávat na FTP svého symfony-hello-world webíku?! :D
- enumag
- Člen | 2118
Kdyby/Autowired jsou 4 třídy + výjimky takže nic velkého. :-) Pokud narážíš na Doctrine anotace tak ano to už je trochu větší záležitost. Používám to abych měl jednotnou syntaxi anotací – anotace používám poměrně hojně ale kdyby každá anotace měla úplně jinou syntaxi (což u knihoven jako ta tvá bývá dost často) tak bych se z toho musel nutně zbláznit.
Kdysi jsem se na velké knihovny díval stejně. Poté co jsem začal používat composer a vyřešil deployment pomocí gitu mne už vůbec netrápí že kromě většiny nette tahám celou doctrine a půlku symfony i na relativně malý projekt. Jsem ale u velkých knihoven dost vybíravý, pokud má něco více než pět tříd a nemá komunitu tak to většinou neberu.
Ten images storage – webchemistry mi též přišel hrozně složitý na to co (ne)umí, je někde veřejně ten tvůj že bych mrknul? Spíše pro srovnání, taky už mám vlastní řešení.
Editoval enumag (6. 1. 2016 22:33)
- Pavel Janda
- Člen | 977
Jasně, že jednodná syntaxe anotací dává smysl. Ještě se nad tím zamyslím.
Je to v pořadí. :) Zatím přepisuji datagrid (haha, další), píšu pro
něj testy a na chvilku to ještě bude.
Pak ty images. A nebo to na chvilku přehodím, klidně. Jak to bude
koukatelné, dám to sem.
- greeny
- Člen | 405
Pavel Janda napsal(a):
@greeny
1, Ano, taky si všude posílám entity. :)create
metodě můžeš jakýkoliv parametr poslat anotací@componentArgs
, například tedy:/** * @var Shop\Product */ public $product; /** * @var App\Forms\ProductFormFactory * @inject * @component productForm:create * @componentArgs product */ public $productFormFactory;
Do metody
create
TovárnyProductFormFactory
ti přijde produkt, který tam naplníš třeba v Action metodě presenteru (ani to nemusí být presenter, dá se to použít v jakékoliv třídě, která extendí PresenterComponent).
Jenže to předpokládám vyžaduje mít tu entitu public (fůj), já radši věci private (stejně je ten presenter final). Další problém se kterým bych se setkal je navěšování eventů na vnořené komponenty (tzn vyrábím komponentu A, v ní je komponenta B a na tu chci navěsit event.
Pavel Janda napsal(a):
2, S tím IDE souhlasím. Na druhou stranu, já zůstávám používat Sublime, IDE je pro mě moc pomalé. Takže to pardon. :)Dík za comment.
Před ±2 rokama bych s tebou o rychlosti IDE souhlasil, ale aktuálně používám PhpStorm 10 a když si 10 vteřin počkám na začátku na indexaci souborů a 10 vteřin na načtení appky, tak runtime je cca stejně rychlej jako sublime (s tunou featurek navíc). :)
- Pavel Janda
- Člen | 977
Před ±2 rokama bych s tebou o rychlosti IDE souhlasil, ale aktuálně používám PhpStorm 10 a když si 10 vteřin počkám na začátku na indexaci souborů a 10 vteřin na načtení appky, tak runtime je cca stejně rychlej jako sublime (s tunou featurek navíc). :)
Ne není. Nemůže být. Rozhodně nesouhlasím. :D
Zkoušel jsem verzi 10 na Retině (2012, stále naprosto nabouchanej komp) a
nedá se to srovnat. Z principu. Nemůže fungovat rychle něco, co je
obrovské a jede v JRE.
Private věci se dají vyřešit reflexí. :D
Vnořené componenty – souhlas, tam je takto jednoduché řešení krátké. Zatím.
- greeny
- Člen | 405
Pavel Janda napsal(a):
Před ±2 rokama bych s tebou o rychlosti IDE souhlasil, ale aktuálně používám PhpStorm 10 a když si 10 vteřin počkám na začátku na indexaci souborů a 10 vteřin na načtení appky, tak runtime je cca stejně rychlej jako sublime (s tunou featurek navíc). :)
Ne není. Nemůže být. Rozhodně nesouhlasím. :D
Zkoušel jsem verzi 10 na Retině (2012, stále naprosto nabouchanej komp) a nedá se to srovnat. Z principu. Nemůže fungovat rychle něco, co je obrovské a jede v JRE.Private věci se dají vyřešit reflexí. :D
Vnořené componenty – souhlas, tam je takto jednoduché řešení krátké. Zatím.
No já jedu na 3 roky starém noťasu za 11k, takže nic moc, ale nikdy se mi nestalo, že by mi IDEčko dělalo nějakou běžnou operaci déle než by bylo vhodné. Kromě vyhledávacích operací (teď myslím třeba Find Usages, který najdou použití dané třídy, nebo Refactor na přejmenování třídy včetně použití – tyhle trvají třeba pár vteřin, zato mám jistotu, že se opravdu nahradí jen na těch místech, kde je skutečně použitá) je tam běžné kódování stejně rychlé jako na Sublime, ale s napovídáním navíc :)
- Martk
- Člen | 661
@PavelJanda Zkoušel jsi vymazat dg/adminer-custom? Když jsem ho tam měl nainstalovaný v základním balíčku, tak se mi často ide seklo na pár vteřin. Phpstorm mám nainstalovaný i na starém pc (± 5 6 let, myslím 8 verzi) a nestěžuji si, i když u počáteční indexaci… ale to se dá přežít.
Můžeš mi ještě říct co znamená 2× chytřejší? Přepisuji totálně toto rozšíření (nelíbí se mi co jsem to vůbec napsal) a zmenší se asi o 50%, ale když to tvoje bude 2× chytřejší, tak bych využil a přidal se k tvému, abych neztrácel čas, pokud ti to nebude vadit.
Editoval Antik (7. 1. 2016 9:37)
- Pavel Janda
- Člen | 977
@Antik Zkoušel jsem PhpStorm používat na více projektech, ale jak jsem psal, z principu to musí být a je pomalejší. :)
„2× rychlejší“ – to bylo s nadsázkou. :P Používal jsem méně
jak polovinu tvé funkcionality – nepoužíval jsem Router, práci
s namespaces, apod. Naopak jsem potřeboval třeba ořezávání obrázků
v makru, ukládání pod poslední dva znaky sha1_file obrázku (automaticky).
Dále třeba vytváření linků přes adresář z důvodu SEO (ne
/images/kitty.100x100.fit.crop10x10x20x20.jpg
, ale
/images/100x100.fit.crop10x10x20x20/kitty.jpg
).
Na nahrávání jsem taky nepotřeboval upload control – pokud už identický
soubor existuje na disku, pouze se naváže kdesi v entitě další vazba a nic
se neukládá. A tak podobně.
Třída tedy skoro nic neumí, je jednoduchá a má cca 300 znaků. K tomu 2 řádky .htaccess-u. Takže ti asi nebude stačit. Do konce týdne se mi to asi podaří prdnout na GitHub.
- Pavel Janda
- Člen | 977
@enumag Surový kód je zde: https://github.com/…mage-storage.
Nějaké krátké demo.
Zatím není Readme, nejsou testy, nejsou v ukázce konfigurace, není hotová
veškerá konfigurace (Zatím je například nutný .htaccess – je to tak
kvůli seu). Vše bude. :)
Edit
Přidána nějaká docu: http://ublaboo.paveljanda.com/image-storage/
Editoval Pavel Janda (13. 1. 2016 9:57)
- newPOPE
- Člen | 648
Ahoj,
uz dlhsie cakam kym niekto zacne riesit komponenty v style https://www.youtube.com/watch?… no zatial nic.
Nakolko som len pozeral doc tak nechcem sudit ci tvoja ext. je dobra
(vyhovuje mi :D) alebo nie.
Este pockam na dalsi vyvoj.
Mam len 2 komenty:
- priklad ktory uvadzas ako prvy (aktualny stav) je trochu nestastny (posielat event na factory nie je moc dobry postup skor by som si urobil form a posiela to na neho s tym, ze ho beriem ako komponentu)
- dost sa to vymyka best practise https://doc.nette.org/…s/form-reuse kde sa presmerovanie a „post callbacky“ riesia v tovarni cize povedzme v presenteri. Kedze je toto vracane automaticky tak kde je moznost si to nastavit?
Editoval newPOPE (12. 1. 2016 10:57)
- Pavel Janda
- Člen | 977
@newPOPE Mně osobně přijde vhodnější vytvářet formuláře
přes továrny v samostatných třídách, nikoliv jako potomky
UI\Control
. Prostě z nějakého důvodu. Ale o to
teď nejde.
Pozor, já nepřidávám eventy té továrně, já proiteruji eventy, které jsou v anotaci a nastavím je objektu, který vrátí ta která factory. Tedy v příkladu:
1, Továrna, která vrací formulář:
class FormFactory
{
public function create()
{
$form = new Nette\Appication\UI\Form;
$form->onSuccess[] = [$this, 'succeeded'];
return $form;
}
public function succeeded($form, $values)
{
echo('Ah');
}
}
Teď bych chtěl v presenteru vytvořit formulář a nabindovat další callback, pokud bude formulář úspěšně odeslaný:
class XPresenter extends Presenter
{
/**
* @var FormFactory
* @inject
* @component form:create
* @componentCallback onSuccess:succeededNumberTwo
*/
private $formFactory; // Mimochodem, už není problém mít tyto property private/protected..
public function succeededNumberTwo($form, $values)
{
echo('oj');
die;
}
}
Po odeslání formuláře mě Nette pozdraví. Pracuji tedy vždy s eventy formuláře.
Další poznámky:
1, Nemusím používat tento addon pouze v Presenterech, lze to ve všech
třídách, které jsou potomkem PresenterComponent
, tedy ve všech
většinou používaných komponentách.
2, Nemusím používat tento addon pouze při tvorbě formulářů, ale
jakýchkoliv komponent. A pokud si vyrobím v komponentě „event
property“, budu moci používat anotaci @componentCallback.