Nejvhodnější připojení presenteru do Komponenty

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

Dobrý den,

s Nette začínám a zkouším tvořit různé komponenty. Chtěl jsem si vytvořit komponenty (model) na zasílání emailů, bude to mí rozšiřující funkce pro Nette\Mail*. Základní otázka ale zní, jak nejlépe jí předat instanci presenteru?

Zkoušel jsem metodu Attached, ale bohužel jsem jí asi nepochopil, nebo nevím jak jí použít.

Můj kód vypadá takto –

/**
 * Emailer
 */
class Emailer extends \Nette\Application\UI\Control
{


        private $presenter;



        /**
         * Konstruktor
         */
        public function __construct()
        {
                parent::__construct();

                $this->monitor('Nette\Application\UI\Presenter');
        }



        protected function attached($obj)
        {
                parent::attached($obj);

                if (!$obj instanceof Nette\Application\UI\Presenter) {
                        return;
                }
        }


        public function test()
        {
                $asd = $this->getPresenter(TRUE)->context->users;
        }

}

Nefunguje. Jak jsem psal, nepochopil jsem to, tak jestli by se našla nějaká duše a napsala mi jak by to teda mělo vypadat správně. Děkuji! :)

Jan Mikeš
Člen | 771
+
0
-

Komponenta a model jsou 2 celkem rozdilne veci!

Dalsi otazkou je, na co potrebujes presenter k odesilani mailu?

Edit: Vidim, ze se snazis pristupovat k nejake sluzbe

$this->getPresenter(TRUE)->context->users;

Lepsi mas si vsechny zavislosti predavat pres konstruktor a delat model (myslim si ze v tvem pripade chces naprogramovat model, ne komponentu) nezavisly na presenteru – model si zaregistrovat v configu jako sluzbu a vsechny zavislosti (pokud budou take zaregistrovany jako sluzby a budou jednoznacne) nette samo vlozi, krom pozadani o tyto zavislosti v konstruktoru se tedy nemusis o zadne propojovani starat.

Editoval Lexi (18. 3. 2013 16:31)

Filip Procházka
Moderator | 4668
+
0
-

Vůbec žádné private $presenter nevytvářej.

class Emailer extends \Nette\Application\UI\Control
{
	// UI\Control monitoruje UI\Presenter by default

	protected function attached($obj)
	{
		parent::attached($obj);

		if (!$obj instanceof Nette\Application\UI\Presenter) {
			return;
		}

		$this->test();
	}


	public function test()
	{
		dump($this->getPresenter()->getContext());
	}

}
Fico
Člen | 8
+
0
-

Pánové, moc Vám všem děkuji za odpovědi. Trochu jsem si s tím pohrál a už jsem to pochopil, zaměňoval jsem Model s Komponentou (základní věc, ano vím). Takže teď už mi to dává smysl.

Ještě jednou, díky!

Fico
Člen | 8
+
0
-

Ještě jeden dotaz, když bych chtěl mít tu komponentu/model? Tak co je vhodnější zvolit? Budu to používat ve více modulech.

Filip Procházka
Moderator | 4668
+
0
-

Co znamená „komponentu/model“ ?

Fico
Člen | 8
+
0
-

To mělo znamenat, jako co z toho zvolit, špatně jsem se vyjádřil.

Tedy jinak, když budu psát něco co mi bude obsluhovat emaily, zda je vhodnější zvolit komponentu, nebo model.

Šaman
Člen | 2666
+
0
-

Model nic není. Je to část aplikace která provádí pracuje s daty, provádí výpočty a zajišťuje konzistenci dat. Model jsou obyčejné třídy, s Nette to nijak nesouvisí.

Komponenta je objekt dědící od Nette\Control a tím si nese nějaké specifické chování. Je zapojena do stromu komponent (nejvýše ve stromu je presenter, proto ho nemusíš nijak injectovat).

Na mailer stačí obyčejná služba (třída), tedy v tvé terminologii model. (Ale komponenty mohou být i součástí modelu, třeba formuláře tam patří určitě.)

Editoval Šaman (18. 3. 2013 20:24)

Jan Mikeš
Člen | 771
+
0
-

Ano, na toto je idealni zaregistrovat si sluzbu v configu jak jsem ti psal vyse, navic si myslim ze v tomto Maileru presenter vubec potrebovat nebudes. Komponenty (objekty dedici od Nette\Control) jsou totiz VETSINOU (nemusi tomu tak vzdy byt) jsou vykreslitelne tridy, ktere maji vlastni sablonu a vykreslujes je pomoci {control tvojeKomponenta} coz ale tvuj priklad neni – ty potrebujes pouze tridu, ktera provadi nejake vypocty a operace, ale nepotrebujes ji vykreslit, je tomu tak? Navic ti staci jedna instance tridy v cele aplikaci, tim padem nemusis nad tim ani uvazovat a zaregistruj si svou tridu jako sluzbu, jak uz ti bylo doporuceno, je to nejlepsi reseni.

Editoval Lexi (18. 3. 2013 21:15)

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

3aman napsal: (Ale komponenty mohou být i součástí modelu, třeba formuláře tam patří určitě.)

Komponenty nemohou být součástí modelu, jsou to vykreslitelné jednotky, tudíž jsou součástí view. A platí, že by v nich neměla být logika, maximálně vykreslovací logika a volání nějakých služeb (modelu). Znám projekty, kde formuláře dělají všechno, a je to peklo.

Šaman
Člen | 2666
+
0
-

Jj, taky teď máme formuláře, které neřeší vykreslování, je to jen seznam políček a pravidel. A to patří určitě pod model (a není to komponenta).

Ale naprostá většina lidí pracuje s formulářem jako s vykreslitelnou komponentou a ta je pak i součást modelu.

Jan Mikeš
Člen | 771
+
0
-

Šaman napsal(a):

Jj, taky teď máme formuláře, které neřeší vykreslování, je to jen seznam políček a pravidel. A to patří určitě pod model (a není to komponenta).

Ale naprostá většina lidí pracuje s formulářem jako s vykreslitelnou komponentou a ta je pak i součást modelu.

Nerad bych te nejak urazil, ale zda se mi ze v tom mas trosku gulas.
https://doc.nette.org/…n/presenters#… model neni kazda trida kterou si vytvoris, tudiz kdyz si das formular do samostatneho souboru a tridu si pojmenujes napr ExampleForm neni to hnedka model – je to proste jen trida.

hAssassin
Člen | 293
+
0
-

@Lexi > myslim ze v tom mas gulas trochu ty (ale jen trochu). Model neni zadna trida, ale je to cela vrstva:

Pojem Model představuje celou vrstvu, nikoliv samostatnou třídu.

A to je dostatecne abstraktni pojem pod kterym si lze predstavit prakticky cokoliv. Co by vsak to cokoliv melo delat je sprava dat a jejich konzistence at uz tim je mysleno cokoliv (treba hromada pisku co mas pred barakem ;). To jestli to tvori jedna, pet nebo deset trid uz zalezi na implementaci.

Jan Mikeš
Člen | 771
+
0
-

Mas pravdu, je to velice abstraktni pojem a kazdy si ho muze vylozit po svem. Ja osobne ale formular obaleny tridou za model nepovazuji :).

hAssassin
Člen | 293
+
0
-

@Lexi > ano v tom s tebou souhlasim, formular je pro me porad komponenta at je obalena jednou nebo 10 tridama. Ale to uz se dostavame trochu OT, takze … :)

Šaman
Člen | 2666
+
0
-

Taková pomůcka pro to co je model je, když si představíte aplikaci ovládanou z konsole, nebo textového terminálu. Tím poměrně spolehlivě eliminujete presenční i view logiku.

A formuláře určitě patří do modelu. Formulář není vykreslitelná komponenta, formulář je seznam proměnných, které je potřeba naplnit a seznam pravidel, která se přitom mají dodržovat.
Informace, že potřebuji proměnnou $name, která nesmí být prázdná, pak $age, což musí být reálné číslo od 5 do 100, to patří pod model. Tyhle proměnné budete potřebovat i když je budete zadávat přes terminál (neřešíme jestli se třeba pohlaví zadá textově, nebo selectBoxem, to je až view).

Presenční logika se do toho začne motat až tehdy, když do formuláře přidáme akci, co se má stát po jeho odeslání. A View se do formuláře dostane v okamžiku, kdy začnu řešit, jak ho vykreslit. Nette formuláře z quickstartu tedy spadají pod M, V, i P.

Nette komponenty nestojí mimo MVP, jen řeší víc věcí najednou, takže často spadají pod všechny části. (Cokoliv co zpracovává data patří do M, pokud to umí pracovat s requestama, tak to je P a pokud to má render metodu, je to i V).
Ale zrovna třída ‚Form‘ není vykreslitelná komponenta, je to čistý formulář (M), jenom ji presenter (P) umí vykreslit pomocí nějakého defaultního rendereru (V).

Editoval Šaman (19. 3. 2013 15:10)

hAssassin
Člen | 293
+
0
-

jasny, chapu a celkem i s tebou souhlasim, ale problem je v tom, ze ja s tridou Form nepracuji a nikdy sem ji snad nepouzil. Pracuju pouze s UI/Form a to uz je vykreslitelna komponenta (pomoci nejakyho svyho rendereru) primo napojena na presenter (takze to ciste pod model patrit nemuze a patri to teda do vsech tri casti).

Spis se ale snazim formulare chapat jen jako prepravky na data, s tim ze view navenek nabizi nejaky rozhrani, kterym jsou data zadany, presenter je nejak vezme a nekam posle (do modelu). a co s nimi udela ten uz je jen a jen na nem. Problemem jsou bohuzel validace ale to se tu uz nekolikrat kdysi resilo (vysledek si uz nepamatuju a ani nemam cas ty vlakna ted hledat). Ostatne pokud mame konzolovou aplikaci tak jako view se da pak chapat i vyzva na vstup od uzivatele, pripadne parametry prikazovy radky, apod…

Šaman
Člen | 2666
+
0
-

Jj, konzolová aplikace by určitě měla P i V, ale bylo by natolik odlišné, že co zůstalo bezezměny, je pravděpodobně M.

Jinak řešit nuance modelu, na to tu není prostor. Zatímco u P a V máme v Nette spoustu best practie návodů, model je dost opomíjen a jediná ukázka je v QS, kde se model smrskl na komunikaci s databází. Proto na otázku co všechno je model má každý trochu jiný názor. Ale na principu jsme se shodli. :)

Editoval Šaman (19. 3. 2013 15:45)

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Stojím si za tím, že formulář není součástí modelu, a podobné výroky mohou být pro spoustu začátečníků matoucí. Formulář je jednoznačně součástí view, a není to jen o vykreslitelnosti – je to o definování popisků, chybových hlášek, o receiveHttpData (velmi abstraktní…) a o ochraně proti CRSF.

Model je business logika. Měl by vystavovat API, které se volá v presenterech, či ve zpracování formulářů, ale tvrdit, že formulář je součást modelu, to je jako tvrdit, že makro {_} je součástí modelu, protote překlady jsou uložené v databázi. Formulář by neměl být s modelem svázán, měl by jen definovat vstupní data od uživatele a nabízet je. Je tedy jednoznačně mostem mezi uživatelem a modelem, ne modelem samotným.

Podobná tvrzení zní abstraktně, ale jejich aplikace často vedou ke kódu, v němž je těžké se vyznat, proto mě to tak doruda rozpaluje :).

Je pravda, že validace by měla být součástí modelu, to ale neznamená, že když formulář definuje validaci, stává se tím součástí této vrstvy.

Šaman
Člen | 2666
+
0
-

Za prvé každý chápeme jinak význam slova formulář. Já pod ním chápu seznam proměnných a jejich omezení, která model potřebuje na vstupu. Ochrany, popisky, ani práce se signály s tím nemají co do činění.
Máš pravdu, že je to matoucí, protože Nette se k formuláři většinou staví jako ke komponentě. Ale Podle hiearchie tříd to komponenta není a abstraktní Form je víc to, co říkám já. UI\Form už se té komponentě blíží.

vojtech.dobes napsal(a):

Je pravda, že validace by měla být součástí modelu, to ale neznamená, že když formulář definuje validaci, stává se tím součástí této vrstvy.

A na tomhle se asi neshodnem. Validace je (nikoliv by měla být) součást modelu a jestliže si formulář data sám validuje, podle mě se stává součástí modelu. Pokud formulář zrušíš a data budeš předávat modelu jinak, přišel jsi o kontrolu konzistence dat, což je odpovědnost modelu.

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Ad validace: „Krávy bučí.“ neznamená „Co bučí, je kráva.“. To jsem se snažil vyjádřit – to, že formuláře obsahují validaci, z nich nedělá model. Ano, validace by neměla být součástí modelu, ale je jeho součástí. Což znamená, že existuje modelová validace (každý projekt ji má unikátní), a formulářová validace (což ve světě Nette jsou metody addRule atd.). Přesná terminologie je velmi důležitá.

Ad tvůj první formulář: ty si přiohýbáš realitu :). Shchválně jsem citoval věci ze třídy Nette\Forms\Form\ . To, že ty nějak formulář chápeš, je sice hezké, ale extrémně matoucí, a s Nette to nemá nic společného.

Šaman
Člen | 2666
+
0
-

Asi máš pravdu, jak s tou třídou Form, tak s těmi pravidly, která nejsou v modelu. Složitější pravidla pak samozřejmě v modelu mám a formulář jen předává hodnoty k překontrolování. V Nette skutečně většina věcí co form zajišťuje spadá pod presenter, případně view, pokud se to týká vykreslení.

Teď mám první projekt, kde se snažím pracovat s formuláři abstraktně, tedy jako s definicí vstupu a nikoliv s komponentou do které píšu data. Proto mi případá, že ten abstraktní fromulář patří víc pod model.

Zjistil jsem, že Yii to dělá podobně, jako se teď snažím já:


Working with Form

Collecting user data via HTML forms is one of the major tasks in Web application development. Besides designing forms, developers need to populate the form with existing data or default values, validate user input, display appropriate error messages for invalid input, and save the input to persistent storage. Yii greatly simplifies this workflow with its MVC architecture.

The following steps are typically needed when dealing with forms in Yii:

  • Create a model class representing the data fields to be collected;
  • Create a controller action with code that responds to form submission.
  • Create a form in the view script file associated with the controller action.

Ale je fakt, že i když je to zajímavá diskuze, do sekce začátečníci nepatří. Tak prosím začátečníky, neřešte to :)

Editoval Šaman (19. 3. 2013 17:40)