Odeslání dat z PHP do JS a naopak
- ForestCZE
- Člen | 209
Ahoj, mám následující kód:
Presenter:
public function handleSnakeScore(): void
{
$lastScore = $this->character->getSnakeScore($this->char->phone_number);
$this->sendJson($lastScore);
}
JS:
function snake()
{
var somePlayedScore = 50;
var url = new URL(location.href);
fetch(url + "&do=snakeScore")
.then(response => response.json())
.then(data => data = lastScore);
console.log(lastScore); //zde se mi vypíše score z databáze, které je podle očekávání
// A nyní potřebuji nějak aktualizovat hodnotu v databázi
if(somePlayedScore > lastScore)
{
// vrať se z JS do Presentru a aktualizuj hodnotu v databázi
}
}
Jak to z JS poslat zase zpět? Jsem z toho nějak mimo. Díky předem za pomoc.
Editoval ForestCZE (8. 7. 2021 5:21)
- David Matějka
- Moderator | 6445
Je zbytečný posílat druhý request. Prostě do toho prvního (třeba do query parametrů) přípoj to skóre. A ten if budeš mít v tom handle.
- dakur
- Člen | 493
@ForestCZE Ono totiž nic jako „vrať se z JS do presenteru“ není. Je browser a server, kteří mezi sebou komunikují. Browser posílá requesty, server odpovídá s response. To je celé. „Vrať se z JS do presenteru“ tedy ve skutečnosti znamená „pošli nový request“. Jestli je ten request synchronní (normální) nebo asynchronní (XHR/ajax), to už je jen detail.
Editoval dakur (8. 7. 2021 9:33)
- dakur
- Člen | 493
Je zbytečný posílat druhý request. Prostě do toho prvního (třeba do query parametrů) přípoj to skóre. A ten if budeš mít v tom handle.
@DavidMatějka To dost záleží na tom, čeho chce docílit. Jestli to chce updatnout v reakci na interakci uživatele, tak potřebuje druhý request.
Editoval dakur (8. 7. 2021 9:33)
- David Matějka
- Moderator | 6445
@dakur Dle kódu to nevypadá, že by mezi requestem a updatem byla nějaká interakce.
@ForestCZE Jo a ten js handler vlastne vůbec fungovat nemůže. V tom druhém then přepíšeš vrácena data nějakou hodnotou lastScore a výsledek serveru zahodis. A za druhé, ten console.log a if se provede okamžitě po vyvolání requestu, nikoliv po jeho dokončení. Ten obsluzny kód tak musíš mít v tom then
- ForestCZE
- Člen | 209
David Matějka napsal(a):
@dakur Dle kódu to nevypadá, že by mezi requestem a updatem byla nějaká interakce.
@ForestCZE Jo a ten js handler vlastne vůbec fungovat nemůže. V tom druhém then přepíšeš vrácena data nějakou hodnotou lastScore a výsledek serveru zahodis. A za druhé, ten console.log a if se provede okamžitě po vyvolání requestu, nikoliv po jeho dokončení. Ten obsluzny kód tak musíš mít v tom then
@dakur Žádná interakce tam není. Já pouze potřebuji vytáhnout poslední score hráče z DB, pak ho provnat s tím, co má v JS na klientovi (co nahrál) a pokud je to nahrané větší než to z DB, tak mu ho aktualizovat v DB.
@DavidMatějka Chápu, jak to myslíš, že se ta data ztratí, ale zbytek nedávám. Jsem z toho ještě víc zmatený než předtím…
- Marek Znojil
- Člen | 90
Pokud zjišťuješ skóre klienta až pomocí JS, tak to proveď pomocí dalšího requestu na endpoint tomu určený (V tvém případě třeba jiný handle.).
- David Matějka
- Moderator | 6445
zadnej dalsi request neni potreba.
var somePlayedScore = 50;
var url = new URL(location.href);
url.searchParams.append('do', 'snakeScore')
url.searchParams.append('newScore', somePlayedScore )
fetch(url.toString())
.then(it => it.json())
.then(it => {
// zpracovani response
})
a handler
public function handleSnakeScore(int $newScore): void
{
$lastScore = $this->character->getSnakeScore($this->char->phone_number);
if ($newScore > $lastScore) {
// update
}
$this->sendJson($lastScore);
}
- ForestCZE
- Člen | 209
David Matějka napsal(a):
zadnej dalsi request neni potreba.
var somePlayedScore = 50; var url = new URL(location.href); url.searchParams.append('do', 'snakeScore') url.searchParams.append('newScore', somePlayedScore ) fetch(url.toString()) .then(it => it.json()) .then(it => { // zpracovani response })
a handler
public function handleSnakeScore(int $newScore): void { $lastScore = $this->character->getSnakeScore($this->char->phone_number); if ($newScore > $lastScore) { // update } $this->sendJson($lastScore); }
@DavidMatějka funguje to parádně. Akorát jsem zjistil, že mi ten JS funguje i takto:
var url = new URL(location.href);
url.searchParams.append('do', 'snakeScore');
url.searchParams.append('newScore', score);
fetch(url.toString());
jakože asi ani není potřeba zpracovávat ten response
bdump mi v Presenteru vrátí správné nové i poslední score.
Je to možné, že to funguje i bez toho? Měl jsem za to, že se ten
response nějak zpracovat musí.
EDIT: dokonce ani $this->sendJson($lastScore);
nepotřebuju.
Nějak to moc nechápu :D
Editoval ForestCZE (8. 7. 2021 21:26)
- Šaman
- Člen | 2667
Jestli to chápu, jediný vstup od uživatele je jeho skóre. Zbytek server zná. Imho by stačil jeden formulář a jeho odeslání. JS jen zařídí to odeslání ajaxově, ale v principu je to stále jen poslat data na server, nechat ho ta data zpracovat a pak překreslit stránku tím, co server vrátí.
- ForestCZE
- Člen | 209
Šaman napsal(a):
Jestli to chápu, jediný vstup od uživatele je jeho skóre. Zbytek server zná. Imho by stačil jeden formulář a jeho odeslání. JS jen zařídí to odeslání ajaxově, ale v principu je to stále jen poslat data na server, nechat ho ta data zpracovat a pak překreslit stránku tím, co server vrátí.
No on to není vstup. To score se přičítá samo na pozadí v JS klientovi. Takže formulář je asi k ničemu.
- ForestCZE
- Člen | 209
David Matějka napsal(a):
Response zpracovávat ani odesílat nemusíš.
@DavidMatějka už ten příspěvek píšu po třetí. Vždycky vidím, jak to funguje, tak si řeknu ok, můj dotaz je zbytečný a pak zase nic. Snažím se překreslit tabulku se score. Jednou se to překreslí, 2× ne a prostě dělá si to, co chce.
Šablona:
{snippet snakesb}
<table class="records records_h">
<tr>
<th>#</th>
<th>Hráč</th>
<th>Body</th>
</tr>
{var $order = 0}
{foreach $scoreBoard as $player}
{var $order += 1}
<tr>
<td>{$order}</td>
<td>{$player->name}</td>
<td>{$player->score}</td>
</tr>
{/foreach}
</table>
{/snippet}
Handler:
public function handleSnakeScore(int $newScore): void
{
if(!$this->character->snakePlayerExists($this->char->phone_number))
$this->character->createSnakePlayer($this->char->phone_number, $this->char->lastname . " " . $this->char->firstname);
$lastScore = $this->character->getSnakePlayerScore($this->char->phone_number);
if($newScore > $lastScore)
$this->character->updateSnakePlayerScore($this->char->phone_number, $newScore);
if($this->isAjax())
$this->redrawControl('snakesb');
}
JS:
var url = new URL(location.href);
url.searchParams.append('do', 'snakeScore');
url.searchParams.append('newScore', score);
fetch(url.toString());
$.ajax({
type: 'POST',
url: url.toString(),
success: function(data){
$("#snippet--snakesb").html(data.snippets['snippet--snakesb']);
}
});
Nevím, co je špatně, ale prostě to funguje úplně na randoma. Někdy to překreslí a někdy ne…