Nette\Application\UI\Control::redirect() neumí přesměrovat jako presenter
- m.brecher
- Generous Backer | 889
Ahoj,
narazil jsem na nejasnost, jak funguje přesměrování komponenty. Testuji přesměrování komponenty na jiný presenter. Komponenta obsahuje formulář s jedním tlačítkem.
Obdržel jsem chybovou hlášku:
Nette\InvalidArgumentException
Component name must be non-empty alphanumeric string, '' given.
Zkusil jsem přesměrovat presenter a to funguje. Nicméně bych si rád vyjasnil, jak přesměrování komponenty funguje, dokumentace přesměrování komponent nijak nevysvětluje.
Z chybové hlášky to vypadá, že metoda redirect() komponenty očekává jako parametr jméno komponenty (jiné ?). Asi na jiný presenter přesměrovat nejde, ale jde v rámci přesměrování na aktuální presenter a akci poslat signál jiné komponentě?
Děkuji za případné komentáře.
Editoval m.brecher (17. 9. 2022 23:25)
- Bulldog
- Člen | 110
Pokud se nepletu, tak link generátor v komponentách nezná rodiče.
A tak by to taky mělo být.
Jeden z principů programování je, že máš programovat třídu k jejímu účelu a ne k účelu nadřízených. Respektive když tvoříš třeba formulář, tak by si jej měl vytvořit tak, aby mu bylo fuk, co se děje okolo, ale zajímal se jen o svou práci.
Pokud by třída věděla o svém nadřízeném (kdo ji používá), tak by
s ním byla svázaná a nedala by se použít jinde, než právě v kompozici
s touhle nadřazenou třídou a to je špatně.
Je to jako by sis chtěl udělat kalkulačku, která počítá jen v rukou
konkrétního Jakuba.
Takže komponenty neví (v rámci odkazování – jinak ví, samozřejmě,
presenter je do nich attachnutý, ale nemusí to nutně být jejich
nadřízený) o nadřízených nic. Takže na ně logicky nemohou
odkazovat.
Komponenty tedy odkazují na signály své/signály svých subkomponent.
Pattern pro psaní odkazů vypadá asi takto:
'(componentName:)*signalName'
Tedy následující odkazy budou směřovat na tyto místa: (pokud předpokládáme, že redirect je použit v komponentě)
Z výše uvedeného plyne, že pokud uděláš odkaz který vypadá
takto:
':Homepage:default'
tak to vezme první dvojtečku a snaží se ji to resolvnout jako název
podkomponenty, podle výše uvedeného patternu, což má za následek to, že
to jako název podkomponenty vezme prázdný řetězec, protože před
dvojtečkou nic nemáš a vyhodí to tvůj error že název komponenty nemůže
být prázdné jméno.
Tvůj druhý odkaz přes presenter samozřejmě funguje, jelikož presenter
zná vše a umí správně redirectovat.
Použití je ale zcela nevhodné, jelikož je to přesně to, co jsem psal a to
svázání třídy (ve tvém případě komponenty) s presenterem. Takto
nemůžeš použít komponentu v aplikaci, kde třeba presentery
nepoužíváš, nebo v aplikaci, kde nechceš přesměrovat, ale jen
překreslit snippet, udělat nějaké další změny atp., jelikož stihneš
v komponentě přesměrovat dřív, než by se další věci vykonaly…
Správné řešení je použití návrhového vzoru Observer, aby se prostě o redirect/překreslení/další side efekty postaral někdo jiný až na něj přijde řada.
Nejjedodušší implementace je použít přímo tu komponentu jako observer a prostě si předat nějaký callback/pole callbacků:
a pak v presenteru:
- m.brecher
- Generous Backer | 889
@DavidGrudl Ano, kapitolu o odkazech v komponentách v dokumentaci https://doc.nette.org/…eating-links#… jsem četl několikrát i včera, ale nevyvodil jsem z toho, že to platí i pro $component->redirect(). Text v dokumentaci:
„… značka {link} i metody komponent jako je link() a další považují cíl odkazu vždy za název signálu…“
je sice naprosto jasný, ale já vyhledával fulltextem přímo ve stránce „redirect(“ a proto jsem to minul.
Obecně je v dokumentaci lepší jednotlivé položky explicitně vyjmenovat, než obecně popsat, protože nováček v Nette to potřebuje po lopatě. Doplnil bych to do dokumentace i sám, ale budu si muset nastudovat, jak se do dokumentace přispívá.
Editoval m.brecher (18. 9. 2022 17:17)
- David Grudl
- Nette Core | 8254
Je to normální git repozitar na https://github.com/nette/doc, asi by to šlo editovat přímo na Githubu
- m.brecher
- Generous Backer | 889
David Grudl napsal(a):
Je to normální git repozitar na https://github.com/nette/doc, asi by to šlo editovat přímo na Githubu
Opravuji, je to https://github.com/nette/docs