dynamické snippety a data-ajax-append

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

Potřebuji udělat pro web hlasování článků.
Článků je více pod sebou, takže potřebuju dynamické snippety, jenže jsem narazil na problém.

<div n:snippet="reload" data-ajax-append>
    {foreach $article as $article}
                   {snippet article-$article->id}
				obsah
                   {/snippet}
    {/foreach}
</div>

Když to je takhle, tak přestane fungovat i snippet reload a nefunguje ani ten article-id.

Editoval slade183 (27. 12. 2012 16:02)

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

Co to znamená, že přestane fungovat? Odesílají se správná data ze serveru? Neobjevuje se nějaká chyba v Javascriptové konzoli?

slade183
Člen | 30
+
0
-

vojtech.dobes napsal(a):

Co to znamená, že přestane fungovat? Odesílají se správná data ze serveru? Neobjevuje se nějaká chyba v Javascriptové konzoli?

Požadavek se pošle, žádná chyba ale snippet se nepřikreslí no

Pošle se místo článku jen snippet snippet article-$article->id

V presenteru mám tento kód který načte další článek

if ($this->isAjax()) {
    $this->template->article = $this->articleRepository->Article(1);
    $this->invalidateControl('reload');
    }

Pro ten druhý snippet ({snippet article-$article->id}) používam v podstatě to samé

if ($this->isAjax()) {
    $this->template->vote=1;
    $this->invalidateControl('reload');
    }

Když odstraním tenhle snippet {snippet photo-$photo->id} tak načítání článků zase funguje

edit: myslím, že to je tím data-ajax-append, asi nepodporuje dynamicke snippety nebo ano ?

Editoval slade183 (28. 12. 2012 11:56)

slade183
Člen | 30
+
0
-

Opravdu nikdo neví, proč to nejde ?

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

Úplně jsem nepochopil, co ti to vrací ze serveru.

data-ajax-append určitě podporuje i dynamické snippety (je to čistě klientská věc, na serveru nečiní rozdíl). Nicméně je třeba pochopit, co to dělá… snippet je vždycky HTML element, standardně <div>. Pokud ze serveru přijde snippet s totožným IDčkem, tak se obsah tohoto divu nahradí tím novým, co přišel v odpovědi. data-ajax-append dělá pouze to, že místo nahrazení se nový obsah připojí před uzavírací značku toho HTML elementu. Záleží tedy co přesně ti vrací server (dej klidně příklad) a jak vypadá vyrenderované HTML.

slade183
Člen | 30
+
0
-

V .latte mam

<div n:snippet="reload" data-ajax-append>
        {foreach $photo as $photo}
                       {snippet photo-$photo->id}
                       {ifset $voted}
                        uz jsi hlasoval
                       {else}

                                                   <div class="votebg">
                                <a href="{link Homepage:default, do => 'likePhoto', id => $photo->id, famous_id => $photo->famous_id, famous_type => $photo->famous->type}" class="vlike" id="ajax"></a>
                                                    </div>
                       {/ifset}
                        {/snippet}
        {/foreach}
    </div>

v presenteru je

public function handleLikePhoto($id,$famous_id,$famous_type)
{
    if ($this->isAjax()) {
        //write like to database
            $like=1;
            $dislike=0;
            $ip=0;
            $this->rateRepository->votePhoto($id,$this->getUser()->getId(),$famous_id,$famous_type,$like,$dislike,$ip);
            //$this->template->photo = array($this->getParam('id'));
            $this->template->voted = 1;
            $this->invalidateControl('reload');
        }
}

firebug odezva:

{"state":[],"snippets":{"snippet--photo-40":"                        uz jsi hlasoval\n","snippet--photo-39":"                        uz jsi hlasoval\n","snippet--photo-38":"                        uz jsi hlasoval\n"}}

presenter na refreshovani fotek

public function handleRefreshPhoto()
{

    if ($this->isAjax()) {
        $count=10;
        $offset=$_COOKIE['photoCount'];
        $this->template->offset=$_COOKIE['photoCount'];
        $this->template->photo = $this->photoRepository->refreshPhoto($count,$offset);
        $this->template->vote = 1;
        $this->invalidateControl('reload');
        }
}

firebug odezva, když chci načíst nové fotky:

"                                                   <div class="votebg">
                                <a href="/realtimefame/www/?do=likePhoto&amp;id=28&amp;famous_id=1&amp;famous_type=1" class="vlike" id="ajax"></a>
</div>
                                                    </div> ...........

když zahlasuju tak mi už jinde hlasování nefunguje, navíc přestane fungovat snippet <div n:snippet=„reload“ data-ajax-append>, protože už nenačte další fotky, načte jen {snippet photo-$photo->id} těch fotek, co se měli načíst…
Když odstraním ten snippet {snippet photo-$photo->id} tak načítání fotek jede jak má.. jenže potřebuju to hlasování tam.

Editoval slade183 (29. 12. 2012 19:38)

slade183
Člen | 30
+
0
-

Už opravdu nevím, zkusil sem podle návodu totéž udělat pomocí komponent ale nefunguje to

presenter: ( to jsem nějak nepochápal s komponentama jsem nikdy moc nepracoval )

protected function createComponentRateControl()
{
    $articles = $this->photoRepository->PhotoId(40);
    return new Nette\Application\UI\Multiplier(function ($articleId) use ($articles) {
        return new Todo\RateControl($articles[$articleId]);
    });
}

komponenta

namespace Todo;
use Nette;

class RateControl extends Nette\Application\UI\Control
{
    private $photo;

    public function __construct($photo)
    {
        $this->photo = $photo;
    }

    public function handleLike()
    {
        if ($this->presenter->isAjax()) {
            $this->template->rate=1;
            $this->invalidateControl();
        } else {
            $this->presenter->redirect('this');
        }
    }
}

Hází mi to chybu:
Nette\MemberAccessException

Call to undefined method Todo\RateControl::render().

MattSkala
Člen | 4
+
0
-

V komponentě ti chybí metoda render, kterou má vykreslit její šablonu. Jak psát komponenty v dokumentaci: https://doc.nette.org/…n/components

slade183
Člen | 30
+
0
-

jo diky Maty, zapomel sem na to a ani ta chyba me nedocvalka :D

edit:Tak už to funguje díiky všem

Editoval slade183 (30. 12. 2012 22:02)

Choice
Člen | 1
+
0
-

Ahoj,

Rad bych otevrel toto tema, kdy z meho pohledu dynamicke snippety a data-ajax-append je problem (rad se budu mylit, a rad budu za jakekoliv rady)

Navazu na predchodi diskusi (z ktereho je problem pomerne jasny) a jen nekoliko malo doplnim (jedna se o reseni, kdy nepouzijeme samostatnou komponentu, a implementace je v ramci presenteru):

Pokud mam dynamicky snippet, a data-ajax-append , tak po uspesnem signalu jsou vraceny JSON data (napr u me ve tvaru: /--„state“:[],„snippets“:{ „snippet–product-72 " : "… \--)
Z tohoto je patrne ze ze se snazi nette invalidovat dynamicky snippet, ale ty data tam jeste nejsou tj nenalezne shodu ID=snippet–product-72 (v DOMu) – jenze pozadovane reseni (alespon v mem pripade by bylo vraceni JSON DAT neco jako: /--"state“:[],„snippets“:{ " snippet–productslist " : " …\--

Tj aby se vratily data do hlavniho snippetu (nikoliv za pomoci jednotlivych dynamickych) a pridaly do DOMU

nicmene invalidace statickeho snippetu invaliduje automaticky (alespon pokud vim) vsechny jednotlive dynamicke…

Doufam, ze jsem se nevyadril prilis zmatene (pripadne se rad pokusim vysvetlit lepe) a nekdo bude schopen mi poradit nejakou fintu (pokud lze impelmentovat za pomoci snippetu v nette ( samozrejme bych si mohl obslouzit response a DOM vykreslit uplne sam jakkoliv potrebuji, ale je to o neco malo vic prace a i do budoucna bych rad vyuzival mechanismu frameworku)

Dekuji za odpovedi,
Choice

(version 2.0.10 released on 2013–03–08)