Nefunkční AJAX success callback

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

Zdravím. Myšlenka je jednoduchá. Metoda createComponentNotes vytváří tabulku. Po kliku na řádek tabulky se zavolá pomocí jQuery AJAXU metoda handleDetails, která by měla zobrazit pomocí ajaxu detaily týkající se dané řádky.

<script>
$('table#dashboard tbody tr').click(function(){
    var idticket = $(this).children('td.grid-cell-idticket').text().replace(/\s/g, '');
    $.ajax({
        url: {link details!},
        type: 'GET',
        data: { 'idticket' : idticket },
        success: function(payload){
            $('#notesTable').html(payload.table);
	    alert('Já se nezavolám.');
        }
     });
});
</script>
public function handleDetails()
        {
            $idticket = $this->getParameter('idticket');
            $this->notesTable = $this->db->formNotesTable($idticket);		//Není důležité
            $this->payload->table = $this->createComponentNotes()->render();
            $this->sendPayload();
        }

Podle firebugu výměna probíhá jak má, dokonce se vrací správně vykreslený grid, ale funkce success se prostě nezavolá. Díky za pomoc…

EDIT: A zapomněl jsem zmínit – na konci té odezvy je {‚table‘:null}… Nevím, co to znamená…

Editoval mere.gee (23. 7. 2013 14:31)

grongor
Člen | 31
+
0
-

@mere.gee: opět zkusím střelit od boku …

// nahrad tenhle radek
// $this->payload->table = $this->createComponentNotes()->render();
// za tohle:
ob_start();
$this->createComponentNotes()->render();
$this->payload->table = ob_get_contents();
ob_end_clean();
mere.gee
Člen | 54
+
0
-

Funguje to! Vysvětlil bys mi prosím, proč? :)

David Matějka
Moderator | 6445
+
0
-

nikdy nevolej createComponent* metody primo, komponentu ziskas pres $this[‚notes‘]

pres ob to je, protoze latte tu sablonu rovnou vykresluje a odesila

a proc vubec pouzivas tenhle zpusob? proc nepouzivas snippety?

mere.gee
Člen | 54
+
0
-

matej21 napsal(a):

nikdy nevolej createComponent* metody primo, komponentu ziskas pres $this[‚notes‘]

pres ob to je, protoze latte tu sablonu rovnou vykresluje a odesila

a proc vubec pouzivas tenhle zpusob? proc nepouzivas snippety?

Protože to mi s ajax.nette nefungovalo. V tom handleru jsem zavolal createComponent a invalidoval jsem příslušný snippet. Navíc takhle se volala createComponent už při vykreslování stránky (protože v templatu bylo {control }, což nechci a nevím, jak to zařídit podmíněně, než si zřizovat nějakou pomocnou proměnnou, což mi přijde jako overkill, když to jde udělat takhle jednoduše.

Takže problém byl s tou podmínkou a asi i způsobem, jak jsem volal tu komponentu. Jak by se to teda vyřešilo pomocí snippetů? Jinými slovy – jak říct v latte: „Blok (komponentu) vykresli, teprve až přijde signál z handlu?“ a jak ten signál správně poslat?

Editoval mere.gee (23. 7. 2013 17:56)

David Matějka
Moderator | 6445
+
0
-

v latte by se nechalo zjistit, jestli se aktualne nejakej signal zpracovava, ale to by nebylo hezky, bez pomocny promenny by ses asi neobesel:

public function handleDetails()
{
	$this->template->showFooComponent = TRUE;
	$this->invalidateControl('foo');
}
{snippet foo}
	{default $showFooComponent = FALSE}
	{if $showFooComponent}
		{control foo}
	{/if}
{/snippet}

Editoval matej21 (23. 7. 2013 18:04)

mere.gee
Člen | 54
+
0
-

Takhle to sice funguje, ale teď bych potřeboval k té vykreslené tabulce ještě přidat jedno tlačítko. Vytvořil jsem podmíněný blok obalený ve snippetu, do kterého jsem se pak z šablony komponenty, kterou jsem vytvořil a která nedělala nic jiného než že se vykreslovala a vytvářela další komponentu (ten datagrid), pokusil vložit to, co potřebuji (control datagrid a to tlačítko), a to pak invalidovat z presenteru. To nefunguje, možná je problém, že vytvářím komponentu v komponentě… Měl bych zkoušet něco jako $parent->addComponent()??

Prosím vás, jak mám vytvořit prázdný blok, do kterého se načte mnou nějak definovaný obsah na signál pomocí AJAXu? Jsem v koncích, přitom to je tak jednoduchá operace…

Editoval mere.gee (23. 7. 2013 19:49)

mere.gee
Člen | 54
+
0
-

Tak jsem udělal následující úpravy… Ta metoda volaná jQuery:

public function handleDetails()
{
	$idticket = $this->getParameter('idticket');
        $notesTable = $this->db->formNotesTable($idticket);
        $grid = $this->createGrid('notesg', $notesTable);
        new NotesList($grid);
        $this->invalidateControl();
}

Ta NotesList:

class NotesList extends Nette\Application\UI\Control
{

    protected $notesGrid;

    public function __construct($grid)
    {
        parent::__construct();

        $this->notesGrid = $grid;
        $this->render();
    }

    public function render()
    {
        $this->template->setFile(__DIR__.'/NotesList.latte');
        $this->template->render();  // Tady na ten řádek to ukazuje Component '' is not attached to 'Nette\Application\UI\Presenter'
    }

    public function createComponentNotesTable()
    {
        //Vykresluju grid...
    }

}

V NotesList.latte mám prostě {control NotesTable} v bloku, kterej je ve snippetu. A vyhazuje to chybu Nette\InvalidStateException: Component '' is not attached to ‚Nette\Application\UI\Presenter‘.

mere.gee
Člen | 54
+
0
-

Tady je screen z callstacku. Možná to má něco společného s tímhle ? Začínám mít pocit, že jde o nějaký bug. Já nevidím důvod, proč by to nemělo fungovat!

Editoval mere.gee (23. 7. 2013 21:59)

grongor
Člen | 31
+
0
-

@mere.gee: problém bude asi v new NotesList($grid); – NotesList je control a tak by jsi ho měl vytvářet přes továrničku v presenter:

public function handleDetails()
{
	$this->getComponent('notesList'); // nebo $this['notesList'];
	$this->invalidateControl();
}

public function createControlNotesList()
{
	$idticket = $this->getParameter('idticket');
	$notesTable = $this->db->formNotesTable($idticket);
	$grid = $this->createGrid('notesg', $notesTable);

	return new NotesList($grid);
}
mere.gee
Člen | 54
+
0
-

Jo, to asi nebylo dobře… Ale tohle téma teď řešíme tady