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).