Nejvhodnější připojení presenteru do Komponenty
- Fico
- Člen | 8
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
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
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());
}
}
- Šaman
- Člen | 2666
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
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
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.
- Jan Mikeš
- Člen | 771
Š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
@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.
- Šaman
- Člen | 2666
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
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
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
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
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
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
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)