Postupné načítání dalších položek – znovu vykreslení všech položek nebo jen přidání?

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

Mám na stránce vypsáno např 10 položek. Při kliku na tlačítko „Další“ se má načíst dalších 10 položek, tím pádem jich má celkem být 20.

Napadlo mě řešení s invalidaci snippetu, takže bych po kliku na tlačítko vyvolalal načtení 20 položek a invalidoval snippet, který by se znovu vykreslil. Jen si nejsem jist, zda-li je překleslení v tomto případě vhodné.

Přidání nových položek mi přijde lepší, tzn. už tam těch 10 položek je, takže je nemá cenu vytvářet znova a jen bych přidal těch dalších 10. Ale pro to už pak nejsou asi snippety vhodné že?

Mé řešení je si z javascriptu ajaxově zavolat nějakou funkci v presenteru, která mi vrátí HTML code, který bych pak přidal za stávající položky. Avšak to pak nemůžu využít Latte, protože kód se mi udělá v presenteru… Není nějaké řešení, které by mi dovolilo použít Latte, ale všechny položky by to nepřekreslovalo?

A zároveň dotaz, zda-li je překreslování celého snippetu opravdu tak nevhodné, jak si myslím?

Dík

Proloo
Člen | 24
+
0
-

Zrovna řeším stejný problém, tak nahodím vejš tohle téma, třeba si někdo všimne :-)
Je nějaká možnost jak jednoduše pouze přidat do snippetu další záznamy (se zachováním starých a bez jejich aktualizace)?
Včera jsem se s tím několik hodin pral a bohužel se mi nepovedlo přijít na funkční řešení.

Tomáš Votruba
Moderator | 1114
+
0
-

Napadá mne načítat do snippetu (js) pouze příspěvky novější než čas refreshe (php).
K inspiraci něco takového:

Šablona

<!-- nové příspěvky -->
{snippet newPosts}
	{foreach $newPosts as $post}
		{$post->text}
	{/foreach}
{/snippet}

<!-- aktuální příspěvky -->
{foreach $posts as $post}
	{$post->text}
{/foreach}

BasePresenter.php

public function startup()
{
	$this->lastRefreshTime = new \Nette\DateObject;
	// save to session maybe, somehow secure not to refresh in handleXxx
	$this->session->lastRefreshTime = $this->lastRefreshTime;
}

public function handleRefreshNewMessage()
{
	$newMessages = $this->context->getPostModel()->getNewerThan($this->session->lastRefreshTime);
	if ($newMessages) {
		$this->template->newMessages = $newMessages;
		$this->invalidateControl("newPosts");
	}
}

scripts.js

function checkNewPosts() {
	$.get("?do=checkNewPosts");
}
checkNewPosts();
setInterval(checkNewPosts, 2000); // every 2 s
redhead
Člen | 1313
+
0
-

A v čem je problém? Využiju snippety a JS kód, který překresluje HTML na straně klienta, změním/upravím, aby data pouze přidal (append() místo html()). Já jsem na to použil Paginator a při každém requestu jen vyrenderuju další „stránku“.

EDIT: samozřejmě jsem zachoval i stávající překreslení snippetů, rozlišuju to třeba nějakou CSS třídou u kontejneru snippetu.

Editoval redhead (23. 8. 2012 13:23)

simPod
Člen | 383
+
0
-

no, takhle jsem to nakonec udelal taky

factor
Člen | 28
+
0
-

Dobré odpoledne,
rád bych se zeptal jak jste vyřešili tenhle problém? Řeším obdobnej problem s periodicky načítaným procentem průběhu aplikace.

Presenter

<?php
public function handleGetProgress()
{
	$progress = $this->ImportModel->getProgress->fetch()->value;
	dump($value) // pokud volám přes ?do=getProgress vrací string

	if($this->isAjax())
	{
		$this->template->progress = $progress;
		$this->invalidateControl("progress");
	}
}
?>

Template

<script src='{$basePath}/js/jquery.js'></script>
<script src='{$basePath}/js/nette.ajax.js'></script>
<script src='{$basePath}/js/netteForms.js'></script>
<script src='{$basePath}/js/jquery.ajaxform.js'></script>

<script type="text/javascript">
	setInterval(function() {
		$.get("{link getProgress!}");
	}, 5000);
</script>

{snippet progress}
	{if empty($progress)}
		0
	{else}
		{$progress}
	{/if}
{/snippet}

Pokud jsem se pokoušel předat informaci o změně proměné $progress pomocí payload, dařilo se mi ji alertovat v js. Bohužel při použití invalidate a snippet nejsem schopen změnit obsah stránky. Nevidíte někdo problém prosím?

Díky

Editoval factor (23. 6. 2013 16:28)

pavelplzak
Člen | 21
+
0
-

Zkus místo $.get volat

$.nette.ajax({
	type: 'get',
	url: "{link getProgress!}"
});

Nevím jestli jde i rovnou $.nette.get , ale asi jo.

factor
Člen | 28
+
0
-

4pavelzak: Bezvadny,funguje, díky moc :)

Nejsem s ajaxem, jquery ani js moc kamarád, mohl by jsi mi prosím vysvětlit jaký je rozdíl mezi tim co jsem postoval a tím co jsi napsal?
Z mého pohledu se stále má vykonat určitej kus php, dokonce „stejným“ způsobem, jen zápis je trošku jinačí.

Díky, díky :)
Ondřej

pavelplzak
Člen | 21
+
0
-

Je to to samé, akorát s nette.ajax.js od Vojty Dobeše musíš ajaxové požadavky volat tímhle způsobem.

jolan
Člen | 5
+
0
-

4pavelzak: po dlouhém trápení mi tvých pár řádků přineslo vykoupení…

pavelplzak
Člen | 21
+
0
-

Jo je divné, že na to není nikde upozorněno, já jsem to objevil taky v nějaké zastrčené diskusi.

newbie
Člen | 31
+
0
-

Nedávno jsem hledal podobné řešení a „nekonečný výpis“ se dá řešit jednoduše: :https://forum.nette.org/…ar-drobnosti#…

vojtech.dobes napsal(a):

V nette.ajax.js je k dispozici datový atribut data-ajax-append, kterým lze vynutit právě appendování místo nahrazení původního obsahu. Stačí udělat něco takového:

<div n:snippet="posts" data-ajax-append="true">
	{foreach $infiniteListOfArticles as $article}
		<h1>{$article->title}</h1>
		{$article->content}
	{/foreach}
</div>