Získanie celej stránky pomocou AJAXového requestu

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

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
+
0
-

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.

livthomas
Člen | 24
+
0
-

Díky, trocha som to preskúmal, ale absolútne netuším, ako to použiť. Okrem stručného prehľadu na githube som k tomu totiž nič viac nenašiel, a keďže jQuery veľmi neovládam, skúmať takmer 500 riadkový zdroják veľmi nemá zmysel.

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

Ukaž ještě odpovídající serverový kód. Konzole v prohlížeči (resp. Firebug) žádné chyby nehlásí?

livthomas
Člen | 24
+
0
-

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
+
0
-

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
+
0
-

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?

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Jop, řeší to automaticky. Tohle vypadá dobře…

livthomas
Člen | 24
+
0
-

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)