Ajaxový odkaz smerujúci na inú action

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

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
+
+3
-

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)

Čamo
Člen | 798
+
0
-

No veď to, akurát som sa aj ja dopátral k tým signálom. Z dokumentácie ajaxu to vôbec nieje jasné. Takže to prepíšem a uvidím.
Díky.

Filip Klimeš
Nette Blogger | 156
+
+2
-

Okay, a já přepíšu dokumentaci :)

akadlec
Člen | 1326
+
+1
-

dokumentaci k čemu?

Ajax může jít jak na signály tak na akce. Tos jen ty špatně pochopil co k čemu je.

Čamo
Člen | 798
+
0
-

Akadlec
No a na to slúži dokumetácia, aby to tam našiel človek vysvetlené. V documentácii sú signály spojené s komponentami a preto by bolo dobré ich spomenúť aj pri ajaxe.

Filip Klimeš
Nette Blogger | 156
+
0
-

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)

akadlec
Člen | 1326
+
+2
-

no ale chlapci nemíchejte jabka a hrušky…ajax je jakási nádstavba. Primárně máte napsat odkazy tak aby fungovaly bez ajaxu a ajaxifikaci pak jen přidat.

Filip Klimeš
Nette Blogger | 156
+
+1
-

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
+
0
-

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
+
0
-

Č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
+
+2
-

@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
+
0
-

@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
+
+1
-

@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
+
+1
-

@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
+
+1
-

@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
+
0
-

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.

Čamo
Člen | 798
+
0
-

Díky.

Čamo
Člen | 798
+
0
-

Prosím vás, tie secured-links nefungujú na action metódy?
Keby niekto aj vedel napísať prečo, tak to bude perfektné.

David Matějka
Moderator | 6445
+
+1
-

@Čamo nefungujou a ani to neni potreba – akce nemaji mazat data apod., to maji delat signaly…

Čamo
Člen | 798
+
0
-

Potrebné to asi nieje, ale fungovať by mali podľa mňa.