Jaká je syntaxe odkazů v LinkGeneratoru?
- maral
- Člen | 25
Ahoj, dneska jsem řešil problém s LinkGeneratorem:
$this->linkGenerator->link("//:SomeModule:SomePresenter:action");
Což vyhodilo chybu Invalid link destination ‚//:SomeModule:SomePresenter:action‘.
Načež jsem se dočetl, že odkazy mají stejnou syntaxi, jako v presenterech (což je zvláštní, s presenterem se mi to vygenerovat podařilo), ale vždy se tvoří absolutní adresy. Tak jsem vyřadil //, a dostal jsem další chybu – Presenter name must be alphanumeric string, :SomeModule:SomePresenter is invalid. To mě vedlo k podezření, že moduly LinkGenerator nezná a neumí. Co v to případě dělat jsem ale nikde nenašel. Stejně tak jsem ani varování před těmito výjimkami neviděl ani v dokumentaci, ani na blogu PhpFashion. Vrátil jsem se zpět k Presenteru, ale rád bych tady na fóru viděl nějakou jednoduchou summary, co lze a co ne, tedy jaká omezení LinkGenerator má.
Mohli byste to někdo jednoduše a přehledně sepsat? Díky moc.
- Yaromil
- Backer | 20
Ahoj,
řeším nyní něco podobného, ale v mém případě se nedaří vygenerovat odkaz na handle, který je v presenteru.
Pokud použiji následující:
<?php
$this->linkGenerator->link("Presenter:handle!");
?>
dostávám zpět Invalid link destination.
Neřešil prosím někdo nebo je zde nějaký pádný důvod, proč by neměl linkGenerator() umět vytvářet odkazy na handle signály?
Díky!
- Yaromil
- Backer | 20
@Felix Díky za odpověď. Jo, zatím odkaz sestavuji ručně, jak uvádíš, ale doufal jsem, že půjde generování odkazu pro handle generovat i právě přes LinkGenerator ;-).
Pořád mi ale přijde, že by LinkGenerator handle mohlo zvládnout také, když to umí vygenerovat odkaz na action, poskládat handle právě z ?do= + parametrů by pro LinkGenerator snad mohlo být reálné ;-), aniž by musel být k dispozici request, ale možná si to představuji moc jednoduše…
Editoval Yaromil (8. 1. 2019 20:34)
- Yaromil
- Backer | 20
@CZechBoY Díky za radu, zkusím tak, jak píšeš. Ale víceméně jde o to, že mám jednoduchou komponentu gridu, která má mimo jiné sloupec, která je typu odkaz a tam si předávám buď klasickou URL nebo cíl pro ‚Presenter:action‘ a nejednou se hodí, když kvůli potřebě AJAXového požadavku můžu odkazovat na handle. Doposud jsem to ale řešil tak, že si odkaz vytvořím přímo v presenteru, kde Grid definuji a převádám ho tedy jako URL.
Jen by se mi líbilo, kdybych mohl využívat následující při definici Gridu a nemusel myslet na další závislosti:
$grid->addColumnLink('link', 'Link:', 'https://nette.org');
$grid->addColumnLink('link', 'Link:', 'Presenter:action');
$grid->addColumnLink('link', 'Link:', 'Presenter:handle!');
U posledních dvou se pak odkaz generuje právě přes LinkGenerator, ale tam je problém s odkazem na signál / handle. Napadá mě teď ještě, že bych v komponentě Gridu mohl přistoupit k rodičovskému Presenteru a tam vyžít klasicky metodu $presenter->link(), ale nebude to asi už tak „čístý“ řešení.
EDIT: tak s tím Presenterem beru zpět, už jsem to vlastně před časem zkoušel a problém je ten, že když ho v komponentě Gridu chci předat např. do třídy pro vytváření odkazů, dostávám zpět: Component '' is not attached to ‚Nette\Application\UI\Presenter‘; tedy jestli to chápu dobře, že v momentě, kdy potřebuji generovat odkaz, není ještě componenta připojena k presenteru a tedy ho ani nemůžu využít, proto jsem dříve sáhl po LinkGeneratoru.
Editoval Yaromil (9. 1. 2019 10:02)
- CZechBoY
- Člen | 3608
A proč bys chtěl uvést odkaz na handle? Co ten handle jako dělá? Nedokážu si moc představit že bych uživatele poslal na nějakou stránku a hned by zároveň odeslal formulář nebo jak?
Pošli kod jak se snažíš použít komponentu dřív než je připojena k presenteru… Očekávám nějaký generování odkazu v konstruktoru nebo tak něco. V tom případě odkaz vygeneruj až při renderování (pokud je to možné).
- Yaromil
- Backer | 20
@CZechBoY V tomhle konkrétním případě komponenta Gridu vytváří v tabulce sloupec s AJAXovým odkazem, který otevře JS lightbox / modalní okno pro editování záznamu v DB. Handle používám právě díky potřebě AJAXového volání.
Dříve jsem to měl vyřešené tak, že jsem odkaz vytvářel až pomocí n:href makra přímo v šabloně Gridu, to fungovalo bez problémů i pro handle, ale od toho jsem musel upustit, protože odkazy nyní potřebuji vytvářet ve vlastní třídě za pomocí \Nette\Utils\Html::el(‚a‘).
Mám to aktuálně funkční, ale hledal jsem nějaké elegantnější řešení (třeba právě pomocí LinkGeneratoru), abych si nemusel odkazy na handle generovat v Presenteru kde se sestavuje komponenta Gridu.
Každopádně děkuji za ochotu!
- Yaromil
- Backer | 20
@CZechBoY Teď nevím, jestli si rozumíme, ale po kliknutí na vygenerovaný odkaz se volá pomocí AJAXu handle (vycházel jsem z dokumentace https://doc.nette.org/…n/presenters#…, kdy je uvedeno, že se používá po potřeby AJAXu) a v tom handlu mám definované něco ve smyslu:
$this->redrawControl(‚projectForm‘);
$this->payload->open_edit_modal = TRUE;
Poslední řádek mi právě pomocí JS otevře lightbox s formulářem pro editaci.
Nechci tedy otevírat novou stránku, ale jen překreslit snippet s formulářem a ten pak zobrazit pomocí JS v lightboxu.
- CZechBoY
- Člen | 3608
A ten formulář už teda ve stránce je a přes handle ho jen zobrazíš
nebo formulář ve stránce ještě není?
Zobrazení lightboxu bych spíš dělal přes javascript než v php. V tom
ajaxovém požadavku bych jen vykreslil formulář – což už může být
klidně jen akce a žádný handle (protože není co překreslit, je potřeba
to teprv poprvé vykreslit).
- Milo
- Nette Core | 1283
@Yaromil Link potřebuješ vygenerovat až v šabloně a když se
šablona vykresluje, komponenta už musí být připojena k presenteru. Takže
getPresenter()->link()
je správná cesta, jen ji voláš moc
brzo. Můžeš to volat rovnou ze šablony, nebo si udělat filtr.
LinkGenerator má pouze router, tedy resolvuje maximálně na úroveň presenteru. On o vnorenych komponentach nic neví.
- Yaromil
- Backer | 20
@Milo Díky moc za odezvu. Jo, teď tomu už rozumím, že LinkGenerator není vhodný pro generování všech odkazů. Ono jde jednoduše o to, jak jsem psal výše, že mám univerzální komponentu na generování tabulek / gridů a tam si můžu definovat sloupec jako odkaz, kde se pak automaticky generují na základě něčeho následujícího:
$grid->addColumnLink('link', 'Link', 'Presenter:action') // tady jsem chtěl docílit mít možnost Presenter:handle!
->setClass('ajax')
->setNewWindow(TRUE)
...
...;
a vzhledem k možnosti různých nastavení odkazů (viz. výše) mi přišlo čistější řešení si pak ve třídě Gridu generovat odkazy pomocí \Nette\Utils\Html::el(‚a‘) než si „zaprasit“ šablonu Gridu kvantem podmínek jen pro potřeby odkazů. Dále je taky dobré, že si můžu např. objekt HTML elementu vytáhnout a dál s ním pracovat.
Každopádně děkuji za radu!
- Yaromil
- Backer | 20
@CZechBoY Mám to udělané tak, že grid presentuje data z DB a nad každým řádkem pak jde dělat klasické operace ©RUD, kdy mám pro každou takovou operaci handle. Na stránce je skrytý shodný formulář, který se pro CREATE a UPDATE musí vždy upravit:
handleCreate:
- vyresetuje formulář
- případně nastaví další nastavení formuláře
- překreslí snippet formláře
- přes payload pošle do JS signál, ať zobrazí lightbox s formulářem
handleUpdate:
- naplní formulář uloženými hodnotami z DB
- případně nastaví další nastavení formuláře
- překreslí snippet formláře
- přes payload pošle do JS signál, ať zobrazí lightbox s formulářem
Pro každý řádek tabulky / akci je tedy formulář nutné nastavit a překreslit, viz. výše.
Když jde o větší formuláře nebo se zobrazení v lightboxu nehodí, pracuji klasicky s renderCreate, renderUpdate, apod.