Jednoduchý counter v Nette s využitím AJAXu, ajax.nette.js
- schnappi
- Člen | 13
Ahoj,
vedel by mi niekto poradiť čo robím zle? Napríklad v príklade nižšie
chcem vytvoriť obyčajný counter, ktorý po kliknutí inkrementuje hodnotu. Na
začiatku ho nastavím na 0. Problémom ale je, že metóda
createComponentMySimpleComponent()
sa vykoná pri každom kliknutí
a teda counter sa vždy vynuluje. Potom sa counter inkrementuje na 1 a tak má
counter hodnotu 1 po každom kliknutí, čo je samozrejme zle.
Prikladám kód:
súbor HomepagePresenter.php:
class HomepagePresenter extends BasePresenter {
/** @var Components\IMySimpleComponentFactory @inject */
public $mySimpleComponentFactory;
public function renderDefault() {
// empty
}
protected function createComponentMySimpleComponent() {
return $this->mySimpleComponentFactory->create();
}
}
súbor MySimpleComponent.php:
class MySimpleComponent extends UI\Control {
private $counter;
public function __construct() {
parent::__construct();
Debugger::fireLog('MySimpleComponent constructor');
$this->counter = 0;
}
public function render() {
$this->template->counter = $this->counter;
$this->template->render(__DIR__ . '/mySimpleComponent.latte');
}
public function handleClick() {
$this->counter++;
$this->redrawControl('counter');
}
}
interface IMySimpleComponentFactory {
/**
* @return MySimpleComponent
*/
function create();
}
súbor mySimpleComponent.latte:
<p>
<a class="myLink" n:href="click!">Refresh!:</a>
<strong>Counter:</strong> {snippet}{$counter}{/snippet}
</p>
- David Matějka
- Moderator | 6445
- Mezi jednotlivymi pozadavky se v php/nette aplikaci neprenaseji ty promenne
(v tomhle pripade
$counter
). To se v nette necha vyresit pomoci persistentnich parametru, takze z counter udelej public property a pridej anotaci@persistent
. Hodnota toho counteru se pak bude drzet v URL. - tim snippetem musis mit obaleny i ten odkaz, jelikoz nyni by stale odkazoval na ten inicialni stav (kde je counter 0)
mrkni se na tenhle example, kde se resi neco podobneho
- schnappi
- Člen | 13
Ďakujem, už to funguje!
Čo ale, ak by som chcel mať zajaxovaný iný element ako <a>, napr. div alebo select? V tom prípade si musím pridať udalosť onClick daného elementu a poslať AJAX request, napr.:
<p>
{snippet counter}
<a class="ajax myLink" n:href="click!">Click!</a>
<div class="myDiv" style="width: 2em; height: 2em; background-color: red; cursor: pointer"></div>
<strong>Counter:</strong> {$counter}
{/snippet}
</p>
<script type="text/javascript">
$(".myDiv").off('click').on('click', function () {
$.nette.ajax({
type: 'GET',
url: {link Click!},
data: {
'mySimpleComponent-value' : 'someValue',
}
});
});
</script>
Ak to takto upravím tak mi to znova nefunguje. Po prvom kliknutí sa counter inkrementuje, ale potom to už nereaguje na kliknutie. Čo mi zase uniká? Súvisí to nejak s tými metódami loadState a saveState? Pretože im veľmi nerozumiem.
Editoval schnappi (14. 2. 2017 19:58)
- CZechBoY
- Člen | 3608
Zkus dát ten .myDiv
ven ze snippetu.
<p>
<div class="myDiv" style="width: 2em; height: 2em; background-color: red; cursor: pointer"></div>
{snippet counter}
<a class="ajax myLink" n:href="click!">Click!</a>
<strong>Counter:</strong> {$counter}
{/snippet}
</p>
<script type="text/javascript">
$(".myDiv").off('click').on('click', function () {
$.nette.ajax({
type: 'GET',
url: {link Click!},
data: {
'mySimpleComponent-value' : 'someValue',
}
});
});
</script>
Případně selector nastavit na document a potom hledat
.myDiv
.
<p>
{snippet counter}
<a class="ajax myLink" n:href="click!">Click!</a>
<div class="myDiv" style="width: 2em; height: 2em; background-color: red; cursor: pointer"></div>
<strong>Counter:</strong> {$counter}
{/snippet}
</p>
<script type="text/javascript">
$(document).on('click', '.myDiv', function () {
$.nette.ajax({
type: 'GET',
url: {link Click!},
data: {
'mySimpleComponent-value' : 'someValue',
}
});
});
</script>
Problém je totiž že nabinduješ událost při onload/onready a potom ten element zmizí a objeví se znova, ale už samozřejmě bez nabindování události (to bys musel znova bindovat po překreslení snippetu).