Quickstart – nesrovnalosti

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

Ahoj,

procházím si quickstart, zatím jsem došel na stránku https://doc.nette.org/…/single-post
Měl bych zatím několik dotazů, ale později jistě přijdou další…

  1. PostPresenter:

Neměl by mít namespace App\Presenters stejně jako HomepagePresnter?

  1. Proč mají presentery přístup k databázi? Neměly by se ptát nějakého modelu?

I na straně „homepage“ je to tak napsané:
„Presenter (nebo Controller) – propojovací vrstva. Presenter propojuje Model a View. Zpracovává požadavky, dotazuje se Modelu na data a vrací je zpět do View.“

Mysteria
Člen | 797
+
0
-
  1. Měl, na GitHubu je to správně.
  2. Presenetery by mít přístup k databázi neměly, ale někdy někdo došel k závěru, že by to pro nováčky bylo moc složité, takže se model vynechal a cpe se do presenterů. Dokonči to bez něj a další cíl můžeš mít přepsat to správně za pomoci modelů. ;)
Ahorn
Člen | 5
+
0
-

Zdravím,

prošel jsem si opět quickstart a bohužel mi nefunguje Autentifikace.
A to konkrétně pokud upravím config.neon.

Mohl by jste mi prosím někdo říci proč. Děkuji

Přidávám chybu

Nette\DI\ServiceCreationException

Service 'user': Multiple services of type Nette\Security\IAuthenticator found: nette.authenticator, 23_App_Model_UserManager

Editoval Ahorn (12. 7. 2014 11:44)

Pavel Macháň
Člen | 282
+
0
-

Ahorn napsal(a):

Zdravím,

prošel jsem si opět quickstart a bohužel mi nefunguje Autentifikace.
A to konkrétně pokud upravím config.neon.

Mohl by jste mi prosím někdo říci proč. Děkuji

Přidávám chybu

Nette\DI\ServiceCreationException

Service 'user': Multiple services of type Nette\Security\IAuthenticator found: nette.authenticator, 23_App_Model_UserManager

@Ahorn Stačí si přečíst tu chybovou hlášku. Máš zaregistrované 2 služby stejného typu (máš tam 2× autenticator).

Pokud chceš aby ti nette dodalo závislosti do služeb atd tak nemůžeš mít 2× stejný typ, protože neví jakou znich dodat. Když je opravdu potřebuješ mít víckrát musíš v configu říct jaká se má automaticky dodávat a jaká ne (vypneš auto inject)

Editoval Pavel Macháň (12. 7. 2014 12:08)

Šaman
Člen | 2666
+
+3
-

No, ono je to pro nováčka matoucí. Authenticator je tam totiž dvakrát, ale skrytě. Jednou ho máš přímo v extension nette v configu, ta ti vytvořila SimpleAuthenticator. A podruhé je to třída UserManager v modelu, která umí ověřovat proti databázi. Vyber si jeden způsob a ten druhý buď vymaž z configu, případně (pokud bys chtěl mít UserManager zaregistrovaný z jiných důvodů, než autentikace), mu můžeš nastavit příznak autowired:no, který způsobí, že se nebude automatocky předávat.

services:
	- class: App\Model\Security\Authenticator
	  autowired: no

P.S. Tenhle zkrácený zápis funguje jen v Nette 2.2
P.P.S. Třída UserManager je podle mě špatně navržená. Měla by se roztrhnout na dvě – jedna pro práci s uživatelem v databázi (UserRepository) a druhá Authenticator. Takhle dělá dvě věci, které spolu nesouvisí, což není známkou dobrého návrhu. A v configu by bylo pak taky jasně vidět, jestli vytvářím, nebo nevytvářím vlastní Authenticator, protože se nebude maskovat za UserManager.

David Matějka
Moderator | 6445
+
+1
-

@Ahorn je to tam zvyrazneno ve velkem zlutem obdelnicku s vykricnikem :) https://doc.nette.org/…thentication

abc
Člen | 92
+
0
-

Mysteria napsal(a):

  1. Měl, na GitHubu je to správně.
  2. Presenetery by mít přístup k databázi neměly, ale někdy někdo došel k závěru, že by to pro nováčky bylo moc složité, takže se model vynechal a cpe se do presenterů. Dokonči to bez něj a další cíl můžeš mít přepsat to správně za pomoci modelů. ;)

Ad 2 – proto čtu quickstart, aby mi ukázal, jak se to dělá a ne abych nad tím přemýšlel a udělal to blbě.
Můžeš uvést příklad, jak by měl presenter získat data od modelu?

Mysteria
Člen | 797
+
0
-

Řešilo se to v několika tématech, tady to máš tak nějak shrnuto: https://forum.nette.org/…senterom-atd#…

Ahorn
Člen | 5
+
0
-

Díky pánové

Šaman
Člen | 2666
+
0
-

abc napsal(a):

Můžeš uvést příklad, jak by měl presenter získat data od modelu?

Velmi jednoduchá aplikace je zde. Pro začátek je to asi nejjednodušší způsob práce s modelem, injectování modelu do presenterů a vytváření formulářů včetně editace. Některé věci sám píšu jinak, třeba trochu složitěji (formuláře v komponentě, nepoužívám anotaci @inject), ale tohle jsem dělal jako ukázku pro výuku, takže jsem používal nejjednodušší možné postupy.

Jediné, co je tam trochu navíc, je obecný repozitář. Ale jak vidíš, zjednodušuje pak vytváření těch konkrétních repozitářů. Pro nejjednodušší aplikace je to podle mě best practise. A až se rozkoukáš, začneš sám zjišťovat, co dělat nějakým pokročilejším způsobem (třeba použít nějaký ORM, traity, jinou strukturu apod).

Taps
Člen | 169
+
0
-

Šaman
Děkuji, pro začátky by se hodilo více takových příkladů :-)

Editoval Taps (12. 7. 2014 19:11)

abc
Člen | 92
+
0
-

Díky, je to pěkné, srozumitelné, úplně bez problémů.
Jen malá poznámka – ten SQL dump by asi mohl vytvářet i databázi (pro mě ale bez problémů).

Ještě jsem chtěl poprosit, zda by nebylo něco složitejšího, abych viděl, jak to potom vypadá.

Díky!

abc
Člen | 92
+
0
-

Např. by mne zajímalo, jak vyrobit komponentu a sdílet ji napříč presentery – dát ji do BasePresnteru?

Šaman
Člen | 2666
+
0
-

abc napsal(a):

Díky, je to pěkné, srozumitelné, úplně bez problémů.
Jen malá poznámka – ten SQL dump by asi mohl vytvářet i databázi (pro mě ale bez problémů).

Ještě jsem chtěl poprosit, zda by nebylo něco složitejšího, abych viděl, jak to potom vypadá.

Díky!

Jsem zastáncem dumpů, které databázi jen naplní. Databází mohu mít více (třeba ostrou, testovací), na produkčním serveru mohu mít její jméno dané poskytovatelem (u freehostingů zadarmo) a zrovna ta moje ukázka byla pro školní potřeby. A když mi vícero studentů odevzdá semestrálku, která si sama vytváří databázi nazvanou třeba ‚nette‘, nebo ‚projekt‘, tak nastává problém. Takže dump databázi jen naplní a programátor ji nejprve vytvoří pod libovolným jménem a to doplní do configu společně s přihlašovacími údaji.

Složitější ukázku zrefaktoruji, aktualizuji na nové Nette a nasdílím. Resp. není o nic složitější, ale jsou v ní pokročilejší postupy.

Ad. komponenta ve více presenterech: Pokud je to komponenta která má být skutečně ve všech, nebo skoro ve všech (třeba přihlášení/odhlášení, resp. nějaký uživatelský panel), tak do BasePresenteru. Pokud ta komponenta má smysl jen v některých presenterech, tak i když se bude kód továrničky opakovat, tak bych ji psal do všech presenterů. Resp. továrnička bude generovaná, takže opakovat by se měla jen jednořádková createComponentFoo(), která zavolá metodu create() nad nějakou tovární službou. Podle mě by mělo být z presenteru poznat, co je k dispozici v šabloně. (Proto jsem zastáncem i prázdných metod renderFoo(), i když by stačilo mít jen šablonu foo.latte a ta by se použila. Ale v kódu by ten pohled foo vlastně neexistoval a mhže to být matoucí.)

Editoval Šaman (14. 7. 2014 0:40)

abc
Člen | 92
+
0
-

Ad. komponenta ve více presenterech: Pokud je to komponenta která má být skutečně ve všech, nebo skoro ve všech (třeba přihlášení/odhlášení, resp. nějaký uživatelský panel), tak do BasePresenteru. Pokud ta komponenta má smysl jen v některých presenterech, tak i když se bude kód továrničky opakovat, tak bych ji psal do všech presenterů. Resp. továrnička bude generovaná, takže opakovat by se měla jen jednořádková createComponentFoo(), která zavolá metodu create() nad nějakou tovární službou.

Lze k tomuto někde dohledat nějaký příklad? (ještě úplně nevím, co kde hledat)

Šaman
Člen | 2666
+
0
-

abc napsal(a):

Ad. komponenta ve více presenterech: Pokud je to komponenta která má být skutečně ve všech, nebo skoro ve všech (třeba přihlášení/odhlášení, resp. nějaký uživatelský panel), tak do BasePresenteru. Pokud ta komponenta má smysl jen v některých presenterech, tak i když se bude kód továrničky opakovat, tak bych ji psal do všech presenterů. Resp. továrnička bude generovaná, takže opakovat by se měla jen jednořádková createComponentFoo(), která zavolá metodu create() nad nějakou tovární službou.

Lze k tomuto někde dohledat nějaký příklad? (ještě úplně nevím, co kde hledat)

K čemu? K obecným továrním službám, nebo ke generovaným továrničkám v Nette?

  1. Vlastní tovární třídu zaregistrujeme jako službu a v presenteru ji použiju v metodě createComponentXxx() (jak vidíš pod tím, mohu vytvořit novou komponentu a opět použít službu aby mi vrátila novou instanci, jen třeba s jiným nastavením)
  2. Ale protože tohle je složitý zápis, tak Nette podporuje generované továrny. Myslel jsem, že generované továrny jsou jen pro jednoduché komponenty bez parametrů, proto je výše uvedená třída psaná ručně. Ale nedávno jsem zjistil, že si mohu nechat vygenerovat i složitější továrničku, takže výše uvedenou továrnu chci zrefaktorovat a nechat ji vygenerovat z interface. Čím míň kódu, tím míň bugů. :)

Editoval Šaman (14. 7. 2014 1:11)