Snippet neobdrží data od handle metody

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

Prosím o radu.
V template mám snippet:

{snippet ceka}
{foreach $ceka as $p}
... <a href="{link zmenaStavu!, $p->id, $p->id_anketa, "false"}">zmena</a>
{/foreach}
{/snippet ceka}

Takto vypadá handle metoda

public function handleZmenaStavu($id, $id_anketa, $stav = "true"){
    Anketa::zmenaStavu($id, $stav);

    $this->template->ceka = Anketa::loadCeka($id_anketa);
    \Nette\Diagnostics\FireLogger::log($this->template->ceka);

    $this->invalidateControl("ceka");
}

FireLogger mi vypisuje data správně, ale odezva vypadá takto:

{"state":[],"snippets":{"snippet--ceka":""}}

Snippet je prázdný a tak se neaktualizuje, ale pouze vymaže.
Poradíte mi proč? Co dělám špatně?
Díky

Editoval Lota (12. 9. 2012 23:44)

h4kuna
Backer | 740
+
0
-

To vypadá jako když dostáváš úplně jiný snippet invaliduješ vypis a v response máš ceka.

Editoval h4kuna (12. 9. 2012 23:54)

Lota
Člen | 38
+
0
-

Ne, to jsem sem špatně opsal. Oba jsou ceka, přepíšu to v původním příspěvku.

h4kuna
Backer | 740
+
0
-

Jsi v metodě handle, která má do vykreslování daleko a snippety se zpracovávaj až když se spustí šablona. Kde se rozhodne zda bude vykreslovat v normálním módu nebo snippetMódu. Taky si posíláš log dřív než invaliduješ.

Lota
Člen | 38
+
0
-

Co z toho plyne?

V tomhle případě je výpis v loggeru pořád správný ale výsledek nikoliv.

public function handleZmenaStavu($id, $id_anketa, $stav = "true"){
    Anketa::zmenaStavu($id, $stav);

    $this->template->ceka = Anketa::loadCeka($id_anketa);

    $this->invalidateControl("ceka");
    \Nette\Diagnostics\FireLogger::log($this->template->ceka);
}

Editoval Lota (13. 9. 2012 0:00)

h4kuna
Backer | 740
+
0
-

Ten stav

<?php
$stav = "true"
?>

je sexy, nebylo by lepší číslo?

"false" == FALSE // je FALSE
"0" == FALSE // je TRUE

Editoval h4kuna (13. 9. 2012 0:10)

h4kuna
Backer | 740
+
0
-

Tím jsem chtěl říct že to posílání do logu nemá smysl, jak jsem psal k invalidaci dochází až při vykreslování tzn až po afterRender(), ne když voláš metodu invalidateControl().

Podle snippetu vidím že to máš všechno na úrovni presenteru?

Nemáš tam vícero snippetů?

Bez ajaxu ti to funguje?

Lota
Člen | 38
+
0
-

Ten stav je prostě string, tam nemusí být „true“/„false“, ale cokoli klidně „ahoj“. Je to jen parametr, jak ten to ovlivní?

h4kuna
Backer | 740
+
0
-

to zavírací makro nemusí obsahovat název snippetu → {/snippet}

Lota
Člen | 38
+
0
-

Mám to na úrovni presenteru. Snippety jsou dva. Bez ajaxu to nefunguje také.

h4kuna
Backer | 740
+
0
-

Lota napsal(a):

Ten stav je prostě string, tam nemusí být „true“/„false“, ale cokoli klidně „ahoj“. Je to jen parametr, jak ten to ovlivní?

viděl jsem jen true/false to bylo navíc, nijak by to ovlivnit neměl. To uzavírací makro by to taky nemělo ovlivnit.

Editoval h4kuna (13. 9. 2012 0:16)

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

Co je obsahem toho $ceka?

Lota
Člen | 38
+
0
-

vojtech.dobes napsal(a):

Co je obsahem toho $ceka?

Pole plné DibiRow

$this->template->ceka = Anketa::loadCeka($id);
public static function loadCeka($id) {
    return dibi::fetchAll('
    SELECT * FROM [tab_anketa_polozky]
    WHERE [stav] = "ceka"
    AND [id_anketa] = %i', $id
    );
}

Editoval Lota (13. 9. 2012 0:23)

Lota
Člen | 38
+
0
-

h4kuna napsal(a):

Tím jsem chtěl říct že to posílání do logu nemá smysl, jak jsem psal k invalidaci dochází až při vykreslování tzn až po afterRender(), ne když voláš metodu invalidateControl().

Podle snippetu vidím že to máš všechno na úrovni presenteru?

Nemáš tam vícero snippetů?

Bez ajaxu ti to funguje?

Bez ajaxu to funguje jen, když změním metodu handle takto:

public function handleZmenaStavu($id, $id_anketa, $stav = "true"){
    Anketa::zmenaStavu($id, $stav);

    $this->template->ceka = Anketa::loadCeka($id_anketa);

    if ($this->isAjax()) {
        $this->invalidateControl("ceka");
    } else {
        $this->redirect("this", $id_anketa);
    }
}
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Kde se nastavuje ta proměnná, když ne v handle?

Lota
Člen | 38
+
0
-

Nastavuje se v render metodě, v handle se pak nastavuje znovu, aby v ní byla aktuální data po změně.

public function renderCeka($id){
    $this->template->ceka = Anketa::loadCeka($id);
}
public function handleZmenaStavu($id, $id_anketa, $stav = "true"){
    Anketa::zmenaStavu($id, $stav);

    $this->template->ceka = Anketa::loadCeka($id_anketa);

    if ($this->isAjax()) {
        $this->invalidateControl("ceka");
    } else {
        $this->redirect("this", $id_anketa);
    }
}
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Zpracování signálu se volá ještě před renderováním. Nemůže to být tím? Zkusil bych dát přiřazení v render metodě do podmínky, jestli proměnná ještě není nastavena.

Lota
Člen | 38
+
0
-

Ha! Funguje! Děkuji za pomoc.
Vůbec nechápu čím je to způsobené, když předtím mi jinde stejný způsob funguje i bez podmínky v render metodě. Rád bych to pochopil, můžeš mi to zkusit vysvětlit? Nebo odkázat někam, kde to zjistím?

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

Hm, $id pro renderCeka se nastavuje v šabloně, že? Teď jsem si všimnul, že to není standardní render metoda. Problém bude v tom, že při AJAXu se vždy volá obyčejná render. Zkus ukázat její kód, tam se asi bude skrývat tajemství :).

Lota
Člen | 38
+
0
-

Co je na téhle render metodě neobyčejného?

public function renderCeka($id){
    if(!isset($this->template->ceka)){
        $this->template->ceka = Anketa::loadCeka($id);
    }

}

Tady se nastavuje $id pro renderCeka

{block content}
<h1>Anketa</h1>

{snippet vypis}
<table n:if="$ankety">
    <th>Titulní foto</th>
    <th>Název ankety</th>
    <th>Upravit</th>
    <th>Stav</th>
    <th>Hlasy</th>
{foreach $ankety as $a}
<tr>
    <td><img src="{$basePath}{$a->foto|bezTecky}" width="180" alt="{$a->nazev}"></td>
    <td><a href="#">{$a->nazev}</a></td>
    <td><a href="{link Anketa:edit, $a->id}">upravit</a></td>
    {if $a->stav == "true"}
        <td>Spuštěna - <a href="{link onOff!, $a->id, "false"}">vypnout</a></td>
    {else}
        <td><a href="{link onOff!, $a->id}">Spustit</a></td>
    {/if}
    <td><a href="{link Anketa:polozky, $a->id}">zobrazit položky ankety</a></td>
    <td><a href="{link Anketa:ceka, $a->id}">čeká na schválení</a></td>

</tr>
{/foreach}
</table>
{/snippet}
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Eh, bylo pozdě večer a já přepnul do jiného kontextu :). Promiň, na té metodě nic zvláštního není (u komponenty by bylo). Pak mě tedy ještě napadá – jsou parametry $id v render metodě a $id v handle metodě ekvivalentní?

Lota
Člen | 38
+
0
-

Možná mi to začíná docházet… parametry $id stejné nejsou. Render má $id – který znamená id ankety a handle má $id – ten znamená id položky v anketě a pak má ještě $id_anketa a to je nečekaně id ankety.

změnil jsem význam $id v handle metodě a..

Voiláá :-) funguje i bez isset v render metodě :-)

Děkuji.