Odkaz na action chce latte soubor (rozdíl mezi odkaz na action a na presenter)
- mimacala
- Člen | 113
Ahojte,
jaký je rozdíl v odkazu na Presenter:default.latte a Presenter:Action.
mám tento kód a když kliknu na tlačítko, tak to po mě chce missing template pridatkosik.latte :/
<div class="col">
<div class="card karty h-100 text-center">
<img src="{$basePath}/assets/img/avatar.png" class="card-img-top w-75 img-profile mx-auto" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.</p>
</div>
<div class="card-footer ">
<a n:href="Produkty:Pridatkosik 1" class="btn btn-primary"> Přidat do košíku</a> // tady posílám ID do presenteru action
</div>
</div>
public function actionPridatKosik(int $idProduktu) // tady zpracovávám
{
$kosik = $this->session->getSection('kosik');
$kosik->set("$idProduktu","$idProduktu");
if($kosik)
{
$this->flashMessage("Zboží bylo přidání do košíku");
}
}
- m.brecher
- Generous Backer | 758
Přidání zboží do košíku je typická funkce kterou řeší nejlépe signál. Pomocí akce presenteru to jde také, má to ale určité nevýhody, které signál nemá. Akce totiž defaultně očekává vykreslení šablony akce. Naproti tomu signál pracuje uvnitř akce/šablony presenteru, nemění ji a automaticky se vykreslí stejná stránka.
Přesměrovat by se ale tak jako tak mělo, protože signál mění obsah databáze – při refreshi stránky se signálem by se samovolně přidalo další zboží.
Signál se pak snadno zapouzdří do komponenty, klidně to ale nech v presenteru
šablona latte:
<a n:href="pridatKosik!, idProduktu: 1" class="btn btn-primary"> Přidat do košíku</a> // link volá signál presenteru
presenter:
public function handlePridatKosik(int $idProduktu) // tady zpracovávám
{
$kosik = $this->session->getSection('kosik');
$kosik->set("$idProduktu","$idProduktu");
if($kosik)
{
$this->flashMessage("Zboží bylo přidáno do košíku");
}
$this->redirect('this'); // aby se refreshí stránky zboží omylem nepřidalo podruhé
}
Editoval m.brecher (13. 10. 2022 16:35)
- m.brecher
- Generous Backer | 758
@Pepino
signál bude fungovat pouze v daném presenteru
Ano, máš pravdu a tak jsem to i myslel. Pokud přidáváme do košíku jenom v jednom presenteru, tak je OK použít signál presenteru a handler signálu umístit do presenteru.
Pokud by se mělo zboží přidávat do košíku ve více presenterech, potom je optimální pro přidání do košíku si napsat samostatnou komponentu a tu do příslušných presenterů pouze zaregistrovat. To je takový doporučený postup na němž se většina komunity Nette shodne.
V Nette jdou věci obvykle dělat více způsoby. Tvůj způsob znamená ve stručnosti – zpracovávat klik na přidání do košíku v akci presenteru a pak přesměrovat.
Pokud budeme přidávat zboží do košíku ve více presenterech, tak to budeme dělat jak? Buďto budeme volat akci jednoho presenteru k přidání do košíku pověřenému, pak ale musíme přesměrovat zpátky na presenter, odkud se zboží přidávalo – to kód zkomplikuje.
Nebo do každého presenteru dáme akci na zpracování přidání do košíku – to kód zduplikuje.
Nebo presentery, kde se přidává do košíku podědíme ze společného abstraktního presenteru, kde bude společná akce pro přidání do košíku. Také komplikované a nepřehledné řešení.
Komponenta je ideální řešení.
- Bulldog
- Člen | 110
Pepino napsal(a):
@mbrecher Komponenty souhlas, ale proč by mělo být komplikace přesměrování z akce zpátky? V nette existuje storeRequest a restoreRequest.
Protože na to redirect není dělaný? :D
Redirect máš pro případy, kdy se člověk odhlásí, když potřebuješ po
odeslání formuláře vymazat request aby nešel odeslat znovu, když máš
zakázán přístup a potřebuješ přesměrovat na přihlášení atp.
Ale po update košíku udělat redirect na jiný presenter a z něj pak
zpátky není ok, protože místo překreslení části stránky (košíku) a
tedy jednoho requestu, který upraví košík do databáze a vrátí snippet
(jednu stránku v případě neajaxového requestu) se provede uložení
aktuálního stavu stránky (včetně requestu, proto store request), což
nastartuje session
pak request na jinou stránku, kde se updatne košík a pak restore request,
který opět nastartuje session, což je redirect a s kódem 302 zpátky na
původní stránku…
Problém je, že to sice udělá restoreRequest, ale ten není klasické přesměrování, takže pokud upravíš košík, tak pomocí RestoreRequestu se stane to, že se stránka po načtení nevykreslí znova. Zavolá se tuším jen metoda startup() a ani se nebude vykreslovat šablona, protože ta je uložena v session v tom requestu…, což má za následek to, že ty změny v košíku v té action metodě se s největší pravděpodobností nepropíšou a košík bude vypadat stejně jako před updatem. Stejně tak se nepřepíšou různé změny v cookies apod., pokud nějaké uděláš.
Takže by jsi musel použít klasický redirect a ne restore request a tedy si posílat URL, kam máš přesměrovat zpátky, což zase přináší problémy s přenášením URL v URL, nebo jiné srandy, protože to se dá podstrčit jiná URL a můžu tak poslat tobě odkaz, který tě pak přesměruje na mou phishing stránku a ukradnu ti údaje atp.
Takže.. Je to správně jak píše @mbrecher … Ideálně
komoponenta, která se o svý překreslování bude starat svým signálem.
Udělá se pouze 1 request bez zbytečného redirectu, nebude se zbytečně
startovat session, pokud máme košík udělaný přes cookies, aby se
přenášel i když se uživatel přihlásí, ušetří to spousty výkonu,
protože se nemusí celá stránka ukládat a pak zase načítat, ušetří to
Bandwidth, protože se bude dělat půlka requestů a na ohromně menší
množství dat a v neposlední řadě je to bezpečnější a
přenositelnější a programátor se méně napíše, jelikož nebude muset
řešit problémy s překreslováním změn, bezpečnost atp.
EDIT
StoreRequest a RestoreRequest se hodí na případy automatického odhlášení,
kdy se chceme vrátit na rozpracovanou stránku po opětovném přihlášení a
to například do poloviny vyplňování formuláře a stránka se nijak
nezměnila od poslední návštěvy.
Signály se hodí na překreslení části aktuální stránky. A to do toho spadá i košík. Navíc, pokud nastane situace, kdy není volán signál ajaxem, ale my potřebujeme zabránit pomocí f5 opětovnému přidání zboží například, tak signál umožňuje redirect na aktuální view velmi jednoduše a nemusíme řešit kam máme přesměrovat a odkud se provedl request.
if ($this->isAjax()) {
$this->redrawControl('basket');
} else {
$this->redirect('this');
}
Editoval Bulldog (13. 10. 2022 21:02)