ublaboo/presenter-component: Jednodušší tvorba továrniček komponent pomocí anotací

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Pavel Janda
Člen | 977
+
0
-

Megajednoduchá pomůcka, zrychlí vývoj. Mrk na GitHub, nebo addon.

Editoval Pavel Janda (6. 1. 2016 14:44)

akadlec
Člen | 1326
+
0
-

No vypadá to zajímavě ale je to už docela „magic“ ne?

Pavel Janda
Člen | 977
+
0
-

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.

Aurielle
Člen | 1281
+
0
-

Magie je to teda dost slušná :) A nevidím v tom moc zlepšení, když bych chtěl i navěšovat callbacky nebo nějak dále vrácenou komponentu konfigurovat. Pro jen zavolání create() na továrničce ale asi v pohodě.

greeny
Člen | 405
+
0
-

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
+
0
-

@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
+
+3
-

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
+
0
-

Čá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
+
0
-

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
+
0
-

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
+
0
-

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á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).

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
+
-7
-

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
+
+1
-

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
+
+2
-

@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
+
0
-

@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
+
0
-

@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
+
0
-

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
+
0
-

@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.

newPOPE
Člen | 648
+
0
-

Pavel Janda napsal(a):

Ok dakujem za priblizenie.