Zpětná hodnota z handleru

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

Ahoj,
lze nějak dostat zpět čistý return z handleru? return mi posle celou stranku.

Příklad:

V šabloně volám ajaxem handler a chci ziskat navratove hodnoty (backdata)

$.ajax ({
	url: '/handlers?do=getMyValue',
	type: "GET",
	data: { 'key_id' : this.id, 'val' : $(this).val()},
	success: function(backdata) {
		alert(backdata);
	},
	error: function(backdata) {
		alert('ERROR:' + backdata);
	}
	});

v presenteru:

public function handleGetMyValue($key_id=NULL, $val=NULL) {
	if (isAjax() .... ) {
		...
		return 'Vse OK';
	}
}

Proc mi to vraci ale celou html stranku a ne jen „Vse OK“?

Šaman
Člen | 2666
+
0
-

Imho nemáš data vracet pomocí return, ale poslat si je jako odezvu.

err
Člen | 77
+
0
-

Jak to prosím tě myslíš?
Pokud vrátím json_encode nad vyvořené pole hodnot, je to to samé. Pokud vrátím echo „OK“ tak je to také totožné.

Vždy mi to vrátí celý template, včetně @layout.latte.

Editoval err (8. 5. 2016 17:06)

Unlink
Člen | 298
+
0
-

Napríklad pomocou sendJson

Editoval Unlink (8. 5. 2016 17:23)

err
Člen | 77
+
0
-

To u me funkcni nebude. Mam nette 2.0.13. Stale to ale nevysvetluje, proc nemuzu poslat vystup z funkce PHP. Pokud poslu zpatky pres return

return json_encode(array('id' => "1", 'data' => "OK"));

Tak mi to stale vraci celou sablonu. Tady tedy vse pro /handlers.

Editoval err (8. 5. 2016 18:20)

jiri.pudil
Nette Blogger | 1032
+
+1
-

Stale to ale nevysvetluje, proc nemuzu poslat vystup z funkce PHP.

Protože ta handle metoda je jenom jedním z kroků v životním cyklu presenteru. Tím, že v ní zavoláš return, sice ukončíš její běh, ale požadavek se zpracovává dál, tj. vykreslí se stránka. Tomu můžeš zabránit právě tím, že životní cyklus presenteru v handle metodě ukončíš, např. odesláním odpovědi – JSON ve 2.0.13 takto:

$this->payload = ['id' => 1, 'data' => 'OK'];
$this->sendPayload();
err
Člen | 77
+
0
-

Děkuji, ale stále mi to nechce docvaknout. Přeskočím námitku, proč když si chci napsat funkci „Hello world!“ musím projet celý presenter a né pouze ten daný handler, který mi to vypíše. Podle toho, co jsi napsal, to znamená, že si na výpis $this->payload musím napsat další funkci sendPayload(), která mi to returnem pošle? Tuším to správně?

A nelze tedy napsat nikoli handler ale jinou funkci, na kterou se prostě odkážu a která nebude tahat celý cyklus presenteru? A jak bych se na ni z ajaxu odkázal, když ne přes ?do=, což je asi automaticky handler?

Editoval err (8. 5. 2016 18:46)

CZechBoY
Člen | 3608
+
0
-

Žádnou metodu sendPayload nepíšeš, v Nette už je.
https://api.nette.org/…ter.php.html#…

err
Člen | 77
+
0
-

Díky, mě to neproběhlo a vyhodilo eroor 500, tak jsem myslel, že tam není. V logu je ale:
Parse error: syntax error, unexpected ‚[‘ in
Takže asi v tom příkladu není to pole definované správně?

Šaman
Člen | 2666
+
0
-

Nepoužívej v tom presenteru return. Handler nemá nic vracet – má něco provést, pak přesměrovat, překreslit, poslat flashmessage, nebo nějakou odezvu. Komu by ten handler něco vracel?
Takže jestli chceš opravdu vrátit jen string ahoj, tak ho echni a pak ukonči presenter pomocí $this->terminate(). Ale pro komunikaci s JS je lepši použít třeba tu sendJson(). Ona už to ukončí sama. Ale žádný return.

Jan Mikeš
Člen | 771
+
0
-

err napsal(a):

Díky, mě to neproběhlo a vyhodilo eroor 500, tak jsem myslel, že tam není. V logu je ale:
Parse error: syntax error, unexpected ‚[‘ in
Takže asi v tom příkladu není to pole definované správně?

Co máš za verzi php? V 5.3 nelze pole zapsat jako []

err
Člen | 77
+
0
-

Mam 5.3. Napadlo me to a opravil jsem pomoci array().

		$this->payload = array('id' => 1, 'data' => 'OK');
		$this->sendPayload();

Coz mi vyhodi opet chybu 500, tentokrat s poznamkou v konzoli: Failed to load response data.

Omlouvam se, uz se skoro stydim.

CZechBoY
Člen | 3608
+
0
-

To jo, ale jaká je chyba v logu?

err
Člen | 77
+
0
-

[2016–05–08 19–08–31] Nette\MemberAccessException: Cannot write to a read-only property HandlersPresenter::$payload.


Tak tomu uz vubec nerozumim. Proc by to melo neco nekam zapisovat?

Editoval err (8. 5. 2016 19:17)

Unlink
Člen | 298
+
+1
-

Priamo payload prepísať nemôžeš, musíš použiť

$this->payload->id = 1;
$this->payload->data = 'OK';
Šaman
Člen | 2666
+
0
-
  1. Říkáš, že ti to hází pětistovku – ty nepoužíváš Tracy, nemáš zapnutý ladicí režim?
  2. Jakou máš verzi Nette? Aktuální, nebo něco historického?
  3. Na jakém řádku ti to vyhazuje ten access error? U sendPauload, nebo tam, kde to plníš?
  4. Práci s payloadem je přímo v dokumentaci, hned ten první příklad.

Editoval Šaman (8. 5. 2016 19:33)

err
Člen | 77
+
0
-

Unlink:
Ahoj. Tohle mi vrati zase celou stranku. Alert jsem zrusil, abych nedelal chybu v parsovani JSON a cely vstup dat davam posilam pres jQuery $(„#backdata“).append(backdata);
Hodnoty mi to nevypise zadne, ale nacte to celou stranku. Tzn. ze mam sablonu v sablone.

Zkousel jsem obe moznosti:
Tahle nevrátí žádná data

$this->payload->id = 1;
$this->payload->data = 'OK';
$this->sendPayload();

Tahle zase vrátí jen celou stránku.

$this->payload->id = 1;
$this->payload->data = 'OK';

Šaman:

  1. Tady je jeste Ladenka. Tu pouzivam, ale u tehle chyby se nic nezobrazi, asi kvuli tomu ajaxu. Chyba je jen v konzoli prohlizece a pak v logu.
  2. Mam 2.0.13
  3. Ted, co jsem napsal, chybu nehaze zadnou, ale data nejsou.
  4. Diky. S dokumentaci mam obas problem, protoze casto zahrnuje priklady, ktere ve starsich nebo naopak v novych verzich nefunguji. Ale ctu ji a snazim se, aby to bylo prvni, kde to hledam. Samozrejme projizdim pred dotazem tak hodinu az nekolik dni Google.
CZechBoY
Člen | 3608
+
0
-

@err vpravo nahoře se dá přepnout verze https://doc.nette.org/…ication/ajax

Unlink
Člen | 298
+
0
-

err napsal(a):

Tahle nevrátí žádná data

$this->payload->id = 1;
$this->payload->data = 'OK';
$this->sendPayload();

A čo to vráti? Ako vyzerá odpoveď.

err
Člen | 77
+
0
-

Dekuji vsem za pomoc.

$this->payload->id = 1;
$this->payload->data = 'OK';
$this->sendPayload();

Tak tohle uz vraci. Musi se na to pustit parser. Protoze mam i starsi jQuery.

Spravne je tedy v handleru to, co jse uvedli a co je vyse a v ajaxu (pokud je to jen jednoprvkove pole, jak je v prikladu):

$.ajax ({
...
success: function(backdata) {
        alert(backdata.data);
    },
...
});

Dekuji, vsem jeste jednou diky. Proste jsou veci, ktere jsem v nette nepochopil a nemuzu se dostat pres starsi zpusoby, kdy jsem si napsal funkci, tu jsem si zavolal a pres RETURN si nechal vratit to, co jsem potreboval.

Navic, kdyz return je k tomu stvorene a jakekoli dlasi provadeni by mel sam ukoncit. Nette, jak jsem prochazel nakonec ->terminate() vola take. Takze to vlastne po trech dalsich funkcich ukonci sam.

Hodne se mi libi latte a jeho makra a navazani na presenter. Vlastni funkce se mi zatim nezazily. Zda se mi, ze to spis odvadi od zvladnuti jazyka nez aby jej to naucilo. Clovek vlastne poradne netusi, co vsechno se taha.

Editoval err (8. 5. 2016 21:03)

Šaman
Člen | 2666
+
0
-

return ale ukončuje jen funkci. ano, handler byl tím returnem ukončen, byla vrácena hodnota (ale nikomu) a presenter dál pokračoval ve svém životním cyklu přesně podle dokumentace.
Fce terminate() ukončí celý tento cyklus – vyhodí výjimku a ta je zachycena speciální obsluhou. Stejnou výjimku vyhazují všechny sendResponse(), sendJson(), …

Nezapomeň, že handler je ten parametr v url ?do=getMyValue, když nepřeruší životní cyklus, tak se provede tento signál a dále se pokračuje na render metodu (v tomto případě asi renderHandlers), která vrátí latte šablonu.

err
Člen | 77
+
0
-

Diky za vysvetleni. Dost jste mi pomohli. Nevim, podle ceho bych hledal funkci s nazvem sendPayload(), pro odeslani JSON. To by byly hodiny. Diky moc!

Editoval err (8. 5. 2016 21:43)

Šaman
Člen | 2666
+
0
-

Jen teda poslední – na JSON je ideální ta sendJson(array|Object), připravíš si pole (může být i hodně rozsáhlé) a pošleš jako json. Ten payload je spíš univerzální nástroj pro komunikaci, zapisují se do něho snippety (asi proto není možné ho přepsat), klidně tam může být půlka věcí nativní z Nette a půlka tvoje. Pomocí sendJson() metody presenteru rovnou odešleš JSON a ukončíš životní cyklus.

Jan Mikeš
Člen | 771
+
0
-

Jen pro úplnost, jak již psal @err výše, ve 2.0.13 sendJson() ještě není.

Funkční příklad s JsonResponse a bez Payloadu ve 2.0.13 by tedy vypadal takto:

use Nette\Application\Responses\JsonResponse;

public function handleGetMyValue()
{
	if ($this->isAjax()) {
		$this->sendResponse(new JsonResponse(array(
			"id" => 1,
			"data" => "Ok",
 		)));
	}
}
err
Člen | 77
+
0
-

Ahoj,
to, co jsem napsal v podekovani skutecne funguje a zdarne to uz pouzivam stale ve verzi 2.0.13
Soucasne plati, ze ve starem jQuery 1.10.2 jeste neni parseJSON(), ale to nevadi, protoze jsou vracena data funkcni. V tom uvedenem popise by tedy alert(backdata.data) vyhodil alert okno s textem „OK“;

Take plati, ze $this->payload lze rozsirovat asi dle libosti. Ja to pak upravil az na:

$this->payload->id = 1;
$this->payload->message = 'OK';
$this->payload->value = $hodnota_zpet;
$this->sendPayload();

Znovu dekuji za pomoc. Hledal bych to hodiny, ne-li dny.
Abych ale neotalel, ted uz pro zmenu resit tvrdsi orisek. Pouzit hodnoty jedne tabulky jako hlavicky sloupcu ve vypisu, hodnoty z druhe tabulky, jako hlavicky radku a hodnoty z treti tabulky pak dle vazeb id nazvu sloupcu a id nazvu radku vypsat. Je to takova ta tabulka zapasu a vysledku a oddilu. Docela si s tim uzivam :-)