Ajaxový odkaz smerujúci na inú action
- Čamo
- Člen | 798
Ydravím vás,
môže mi prosím niekto vysvetliť ako má fungovať ajaxový odkaz na inú
akciu?
Zobrazujem renderDefault($article_id) z ktorej vedie ajaxový odkaz na
actionDelete($comment_id).
actionDelete vyzerá asi takto:
public function actionDelete($id)
{
...
$this->setView('default');
$this->template->article = $article = $this->blogComments->findOneBy(array('id' => (int)$id), 'admin')->ref('blog_articles', 'blog_articles_id');
//$this->blogComments->delete((int)$id);
$this->flashMessage('Komentár bol zmazaný.');
//$this->redrawControl('flash');
//$this->redrawControl('comments');
}
Zakomentované je to preto, že nič z tej ajaxovej časti nefunguje.
Problém je s tou premennou article. Šablona na mňa vyhadzuje, že trying to
get property of non object …$article->title… Pritom {dump $article} mi
vypíše normálny platný active row.
- Filip Klimeš
- Nette Blogger | 156
Moc nerozumím tomu, kde Ti šablona vyhazuje tu chybu, resp. kde
přistupuješ k $article->title.
Nebylo by možná lepší udělat AJAXový subrequest, tedy místo
actionDelete($id)
udělat
public function handleDeleteComment($id)
{
$this->blogComments->delete((int) $id);
$this->flashMessage('Komentár bol zmazaný.');
if ($this->isAjax()) {
$this->redrawControl('flash');
$this->redrawControl('comments');
}
}
a potom vytvářet odkaz jako n:href="deleteComment! $id"
?
EDIT: koukni sem. Možná by se v kapitole o AJAXu mohlo o subrequestech povědět víc, není na první pohled patrné, jak se takovéhle akce mají správně dělat.
Editoval FilipKlimeš (11. 2. 2015 12:25)
- Filip Klimeš
- Nette Blogger | 156
akadlec napsal(a):
dokumentaci k čemu?
Ajax může jít jak na signály tak na akce. Tos jen ty špatně pochopil co k čemu je.
Dokumentaci k AJAXu. 95% AJAX požadavků, co jsem kdy použil, bylo na subrequest. Možná by bylo dobrý tam vysvětlit jak a kdy co použít :)
Např. v presenters stojí „Metoda zpracovává tzv. signály neboli subrequesty. Určeno zejména pro komponenty a zpracování AJAXových požadavků.“, ale v ajax už není žádná obecnější zmínka. Opravit dokumentaci k AJAXu už je ale v plánu déle :)
Editoval FilipKlimeš (11. 2. 2015 18:21)
- Filip Klimeš
- Nette Blogger | 156
Nejsem si jistý, že se bavíme o stejné věci. Ano, funkcionalita s AJAXem a bez je jedna věc, druhá věc je dokumentace AJAXu, kde chybí vysvětlení co jsou a kdy a jak použít (sub)requesty.
EDIT: mám pocit, že mazání komentáře lze naprosto s klidem provést subrequestem. View se nijak nemění, přijde pouze flash message a překreslí se snippety. Pokud by nefungoval AJAX, provede se subrequest a překreslí se celá stránka. Tohle je IMHO učebnicové použití AJAXu + subrequestu a v dokumentaci není uvedeno. Chtělo by ho to přidat.
Editoval FilipKlimeš (11. 2. 2015 18:46)
- Čamo
- Člen | 798
Akadlec
Dnes asi nieje tvoj deň brácho :D
Filip
Ak je to v tvojej kopetencii tak by bolo fajn to doplniť. Neviem ako sa docu
píše ale predstavujem si to tak, že sa chytí text doplnia sa 4 vety a
commit. Prečo je to taký problém? Samozrejme nechcem zhadzovať to čo je
napísané, len ma to mrzí, lebo je to na škodu veci.
- Filip Klimeš
- Nette Blogger | 156
Čamo napsal(a):
Filip
Ak je to v tvojej kopetencii tak by bolo fajn to doplniť. Neviem ako sa docu píše ale predstavujem si to tak, že sa chytí text doplnia sa 4 vety a commit. Prečo je to taký problém? Samozrejme nechcem zhadzovať to čo je napísané, len ma to mrzí, lebo je to na škodu veci.
Taky nechci nic shazovat :) momentálně pracuju na jiné kapitole, ale až ji dokončím, vrhnu se na AJAX. Ano, upravíš dokumentaci, uděláš commit a pak pošleš pull-request do nette/docs.
- Etch
- Člen | 403
@FilipKlimeš:
Toto ale opravdu nesouvisí moc s ajaxem samotným. Tohle je více o „nenastudování životního cyklu presenteru“ (či nenastudování rozdílu mezi signálem a action a prací s parametry), protože tak či tak se lze v dokumentaci „doklikat“ k větě „Signál (aneb subrequest) je komunikace se serverem pod prahem normálního view, tedy akce, které se dějí, aniž by se změnilo view.“ a tedy, že danou funkčnost lze udělat jak pomocí action i pomocí signálu
namespace App\Presenters;
class HomepagePresenter
extends BasePresenter{
public function renderDefault($value){
if(!$this->ajax AND !empty($value)){
$this->template->value = $value;
}
}
public function actionDelete(){
$value = $this->action;
if(!$this->ajax){
$this->redirect('default', ['value' => $value]);
}
$this->view = 'default';
$this->template->value = $value;
$this->redrawControl('snippet');
}
public function handleRemove(){
$value = $this->signal[1];
if(!$this->ajax){
$this->redirect('this', ['value' => $value]);
}
$this->template->value = $value;
$this->redrawControl('snippet');
}
}
{default $value = 'default value'}
{block content}
<a n:href="default">Reset</a><br>
<a n:href="remove!" class="ajax">Signal (with Ajax)</a><br>
<a n:href="delete" class="ajax">Action (with Ajax)</a><br>
<a n:href="remove!">Signal (without Ajax)</a><br>
<a n:href="delete">Action (without Ajax)</a><br>
<br><br>
{snippet snippet}
{$value}
{/snippet}
{/block}
To, že přesune danou operaci z action do signálu neřeší ten problém, že nezná cyklus presenteru a na každém dalším krapet složitějším požadavku se ihned zasekne.
Podlě mě mu ta úvodní věc umře celkem logicky na
trying to get property of non object
protože v
renderDefault
bude mít něco na způsob:
public function renderDefault($id){
$this->template->article = $this->blogArticles->findOneBy(array('id' => (int)$id)); /** (Nevím jak se přesně používá nette database (nebo co to je :) ) takže je to jen obrazné) */
/**
* ...
* ...
*/
}
Výsledek je ten, že si vytvoří link na actionDelete něco ve smyslu:
<a n:href="delete, id => $comment->id">Smazat</a> // čímž změní ID článku na ID komentáře
což vede na „actionDelete($id)“ kde se provede nějaké mazání (nebo taky klidně nic) a změní se „view“ zpět na „default“ v „renderDefault“ to zase bude chtít načíst článek z DB jenže už ho to bude hledat podle ID komentáře (které si před tím krásně prohodil), což pravděpodobně vrátí „NULL“ no a jsme doma. :)
Tak jako tak to podle mě nemohlo fungovat s ajaxem ani bez něj a pokud to „fungovalo“, tak to byla jen souhra náhod a jen díky tomu, že zrovna byl Merkur v konjunkci s Venuší.
PS: Neříkám, že by se dokumentace ohledně ajaxu neměla upřesnit a třeba tam i dopsat, kdy je většinou vhodnější použít signál a kdy action, ale zrovna v tomhle případě bych neviděl problém v dokumentaci k ajaxu, ale v celkovém nepochopení životního cyklu presenteru a obecně prací s parametry.
Editoval Etch (14. 2. 2015 9:40)
- Filip Klimeš
- Nette Blogger | 156
@Etch:
Wow, díky za vyčerpávající rozbor :) máš pravdu.
@akadlec:
Promiň, špatně jsem pochopil Tvůj dřívější příspěvek. Samozřejmě
máš pravdu, k závěru co jsi naznačoval, bych došel časem taky.
Subrequesty jsou momentálně nejlépe vysvětleny u komponent, ale viděl jsem
je mnohem častěji používané u AJAXu. Proto jsem je chtěl lépe vysvětlit
v kapitole ajax (a dát dobrý příklad), ale zároveň je
přesunout z components do presenters.
Moje myšlenka byla taková, že člověka (zejména začátečníka) napadne použít AJAX. Proč ne, je to přeci cool a v Nette dobře udělené. Rovnou ho k tomu napadne i funkcionalita (koho z vás taky hned nenapadlo mazání, nebo něco velmi podobného). Potom by měl v kapitole o AJAXu být nasměrován správnou cestou. Proč je správná pochopí až později, kdy si dostuduje životní cyklus a zpracovaní requestů.
Editoval FilipKlimeš (14. 2. 2015 10:24)
- Etch
- Člen | 403
@FilipKlimeš:
Zrovna u toho mazání přes signál mi to přijde v dokumentaci trochu „dvojsečné“.
- Ano, je to krásný příklad.
- Ano, je to cool.
- Ano, je to první věc, která každého napadne.
- Ano, je to v nette věc na pár řádků.
jenže má to jedno podstatné „ale“ a to právě minimálně z pohledu začátečníka.
Muselo by tam být minimálně 3× rudým písmem zdůrazněno, že je to nutno bezpodmínečně ošetřit proti CSRF.
Ovšem i v tom případě si nejsem úplně jist, že by se tím nějaký „začátečník“ zdržoval. :)
Editoval Etch (14. 2. 2015 12:05)
- Filip Klimeš
- Nette Blogger | 156
@Etch:
Parádní postřeh! V tom případě by to ale stejně chtělo někam do dokumentace doplnit, že signály představují CSRF riziko. Donedávna, než jsem si poslechl jednu starší přednášku od @JanTvrdík, jsem o něm sám nevěděl. Možná by si signály zasloužily samostatnou kapitolku?
Editoval FilipKlimeš (14. 2. 2015 12:50)
- akadlec
- Člen | 1326
@FilipKlimeš a to je právě ten problém začátečníka, moc toho neumí ale hned bych těl umět udělat eshop (nenarázím na nikoho zde) místo toho aby se prokousal základy a zjistil proč je tohle tak a tak. Jak tady @Etch zmínil, je to o pochopení životního cyklu aplikace.
Jinak třeba to uvedené delete…ve většině případů chce tu akci potvrdit zda uživatel tu akci opravdu chce udělat, takže se dá krásně využít komponenty/extension co to vyřeší a zárovně ošetří proti útoku ;)
- Čamo
- Člen | 798
Počkať počkať!
Prepáčte že reagujem s oneskorením. Nevšimol som si čo sa tu
udialo…
Musím sa spýtať ako riešiť to CSRF pri signáloch. Chápem, že treba
pridať nejaký token, ale ako to implmentovať, aby tam ten token neostal?
Môže to niekto popísať.
Tiež by som bol za to, aby tie signály mali vlastnú kapitolu.
- David Matějka
- Moderator | 6445
@Čamo nefungujou a ani to neni potreba – akce nemaji mazat data apod., to maji delat signaly…