Nittro – events po skončení requestu

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

Zdravím, nevíte někdo zkušenější, jak to má nittro s eventy, existuje nějaký způsob jak zjistit dokončení ajaxového požadavku. Potřebuji spustit určitý js kód po dokončení a invalidaci snippetu a tak nějak nevím jak odchytnout událost že ajax se dokončil v pořádku a snippet se invalidoval.

Díky moc za rady.

jahudka
Člen | 71
+
+1
-

DominikDvorak94 napsal(a):

Zdravím, nevíte někdo zkušenější, jak to má nittro s eventy, existuje nějaký způsob jak zjistit dokončení ajaxového požadavku. Potřebuji spustit určitý js kód po dokončení a invalidaci snippetu a tak nějak nevím jak odchytnout událost že ajax se dokončil v pořádku a snippet se invalidoval.

Díky moc za rady.

Ahoj,

záleží malinko, jakou package používáš – pokud používáš nittro-page, máš jen jednu možnost:

<script>
_context.invoke(function(page) {
    page.on('update', function(evt) {
        // evt.data === payload, takže
        // evt.data.snippets bude objekt klíčovaný
        // podle ID snippetu - pokud objekt nějaké
        // ID obsahuje, snippet byl invalidován.
        // Událost "update" se spouští po aplikaci
        // všech snippetů a spouští se taky při
        // úplně prvním načtení stránky, kdy ale
        // žádný payload nebyl poslán, takže objekt
        // evt.data.snippets vůbec nebude existovat.
    });
});
</script>

Pokud používáš nittro-application nebo nittro, můžeš to samé udělat pomocí:

<script>
_context.invoke(function(di) {
    di.getService('page').on('update', function(evt) {
        /* ... */
    });
});
</script>

A pak má služba Page samozřejmě taky událost error – pokud AJAX požadavek selže, update se nevolá.

S nittro-application a nittro máš ale ještě jednu možnost, a tou je sáhnout si přímo na AJAX request objekt:

<script>
_context.invoke(function(di) {
    di.getService('ajax').on('request-created', function(evt) {
        evt.data.request.on('success', function(evt) {
            // evt.data.getStatus() (int),
            // evt.data.getPayload() (string|object),
            // evt.data.getHeader('...') (string)
        });

        evt.data.request.on('error', function(evt) {
            // evt.data.type ('abort'|'connection'|'response'|'unknown')
            // evt.data.status (null|int)
            // evt.data.response (null|Nittro.Ajax.Response jako u success eventu)
        });
    });
});
</script>

Tím se k payloadu dostaneš ještě předtím, než ho zpracuje Page service, a pokud chceš bejt hodně hacky, tak můžeš payload i změnit (protože je to objekt a ty se v js předávaj jako reference).

Editoval jahudka (25. 4. 2016 3:47)

jahudka
Člen | 71
+
+1
-

A pak je ještě otázka, jestli na to nejdeš špatně (nebo tě jenom špatně chápu) :-) jestli správně chápu tvůj use-case, máš nějakej kus JS, kterej má spustit nějakou akci a reagovat na její výsledek..? Ty řešení nahoře jsou pro „application-wide“ situace, ale pokud jde o jedno konkrétní místo, kde potřebuješ reagovat jinak než všude jinde, dávalo by větší smysl použít přímo Promise, kterej vrací metody Nittro.Page.Service.open*() – například:

<script>
_context.invoke(function(di) {
    document.getElementById('customlink').addEventListener('click', function(evt) {
        // není třeba volat evt.preventDefault(), openLink() ho zavolá sama,
        // pokud se podaří request odeslat AJAXem - jinak nechá click
        // zpracovat normálně browser
        di.getService('page').openLink(evt.currentTarget, evt)
            .then(function(payload) {
                // spustí se vzápětí po "update" události služby Page
            }, function(err) {
                // chyba
            });

    });
});
</script>

Editoval jahudka (25. 4. 2016 3:44)