Získanie celej stránky pomocou AJAXového requestu
- livthomas
- Člen | 24
Zdravím,
už dlhšiu dobu sa bavím s infinite scroll v Nette. Pôvodne som to mal
vyriešené tak, že pre jeden snippet, ktorý obsahoval jednu stranu
príspevkov, som namiesto .html() volal .append(), a tak sa mi
vždy na konci stránky pridávali ďalšie „strany“ príspevkov. Bolo to
jednoduché a funkčné riešenie, no len do chvíle, kedy som do tohto snippetu
pridal ďalší, v ktorom bolo tlačítko pre hodnotenie príspevku.
Keďže ma nenapadlo iné riešenie infinite scroll pomocou snippetov, rozhodol som sa, že to urobím bez nich. Mám však jeden problém. Potreboval by som pomocou AJAXu získať HTML obsah, ktorý vracia daný presenter pri zavolaní konkrétnej akcie. No Nette mi namiesto celej stránky vždy vracia len snippety. Ako to môžem obísť a pri tomto konkrétnom requeste získať celú stránku s tým, že pri ostatných to bude naďalej vraciať snippety?
- Vojtěch Dobeš
- Gold Partner | 1316
Přesnou odpověď z hlavy nevím, ale můžeš se mrknout na
nette.ajax.js
, v aktuální master verzi je pro infinite scrolling
zabudovaná podpora, jednoduše lze rozlišit, které snippety se mají
nahrazovat, a které appendovat.
- Vojtěch Dobeš
- Gold Partner | 1316
Okej, není třeba víc než (jak doplněk správně zapnout je popsané myslím docela dobře, na addons.nette.org je český překlad):
$.nette.init();
A pak udělat inkriminované snippety (ty, kter se mají appendovat a ne nahrazovat) takto:
<div n:snippet="foo" data-ajax-append>
V dokumentaci o tom ještě není zmínka, protože je to v masteru a ne ve stabilní verzi.
- livthomas
- Člen | 24
Díky, ale stále mi to nechce fungovať. Neviem, či niečo náhodou neprehliadam, ale podľa informácii v doplnkoch by malo nette.ajax.js automaticky „zAJAXovať“ všetky odkazy s CSS triedou ajax. No nespráva sa to tak, kým vo svojom skripte neuvediem:
$('a.ajax').live('click', function (event) {
event.preventDefault();
$.nette.ajax({
type: 'get',
url: $('a.ajax').href
});
});
- Vojtěch Dobeš
- Gold Partner | 1316
To je dost děsivý kousek Javascriptu, obávám se že i nefunkční… nette.ajax.js akorát vyžaduje inicializaci, viz příspěvek výše – ta by měla být zavolána na událost document.ready. Viz dokumentace nette.ajax.js, tam jsou všecky ukázky kódu.
- livthomas
- Člen | 24
Stále som to nejak nerozbehal. Pôvodne som to vyriešil inak, úpravou jednoduchšieho jquery.nette.js, no moje riešenie sa ukázalo ako veľmi neefektívne, preto by som to rád urobil cez nette.ajax.js. Akurát, že do JavaScriptu sa naozaj nevyznám a neviem, prečo mi nefunguje niečo takéto:
Inicializácia nette.ajax.js:
$(function () {
$.nette.init();
});
Zobrazenie príspevkov:
<div class="posts" n:snippet="posts" data-ajax-append>
<div class="post" n:foreach="$posts as $post">
{control postControl-$post->id}
</div>
</div>
Prepínanie na ďalšiu stranu:
{snippet pageControl}
<div class="page-nav" n:if="!$paginator->last">
<a n:href="$presenter->getAction(true) $paginator->getPage()+1" class="ajax" id="nextpage">
<img src="{$basePath}/img/page-next.png" alt="{_"Show more"}" title="{_"Show more"}">
</a>
</div>
{/snippet}
Teraz mi to robí to, že namiesto pripojenia ďalších príspevkov za aktuálne zobrazené, mi to normálne (neajaxovo) načíta ďalšiu stránku.
- Vojtěch Dobeš
- Gold Partner | 1316
Ukaž ještě odpovídající serverový kód. Konzole v prohlížeči (resp. Firebug) žádné chyby nehlásí?
- livthomas
- Člen | 24
Máš na mysli kód presenteru? Ten vyzerá nejak takto:
public function renderList($page = 1) {
$paginator = new \Nette\Utils\Paginator;
$paginator->setItemCount($this->postList->count('*'));
$paginator->setItemsPerPage($this->settings->post_per_page);
$paginator->setPage($page);
$this->template->paginator = $paginator;
$this->template->posts = $this->postList->order('id DESC')->limit($paginator->getLength(), $paginator->getOffset());
}
Konzola nič nehlási.
- Vojtěch Dobeš
- Gold Partner | 1316
V tom presenteru bude třeba ty snippety invalidovat.
Jinak netuším, proč se ti to ajaxově neodesílá, ujisti se, že máš správně načtené jQuery (min. 1.7), potom nette.ajax.js, a až potom ten inicializační kousek kódu.
- livthomas
- Člen | 24
Snippety invalidujem v predkovi (v mojom prípade BasePresenter):
public function beforeRender() {
parent::beforeRender();
if ($this->isAjax()) {
$this->invalidateControl();
}
}
A skripty načítavam v tomto poradí (my.js je súbor, kde volám
$.nette.init()
):
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="{$basePath}/js/nette.ajax.js"></script>
<script type="text/javascript" src="{$basePath}/js/my.js"></script>
Tipujem, že mi tam ešte niečo chýba. Pri jquery.nette.js totiž ešte trebalo ošetriť kliknutie na tlačítko triedy ajax, no nette.ajax.js by to mal robiť automaticky, nie?
- livthomas
- Člen | 24
Skúšal som to na inej stránke (bez infinite scrollu). V konzole vidím, že sa mi vrátil snippet, ktorého obsah sa zmenil, no na stránke sa neprekreslil.
EDIT: Nefunguje ani to odoslanie requestu. Mal som tam len zabudnutý kus kódu, ktorý pri kliknutí na odkaz, AJAXovo načítal stránku, na ktorú odkazoval.
Editoval livthomas (18. 3. 2013 14:41)