Nittro – zrušení / deaktivace skriptu při přechodu na další stránku

jahudka
Člen | 71
+
+2
-

@couda se mě zeptal přes PM, ale nejde mu odpovědět (server říká, že e-mailová schránka neexistuje), tak to zkusím tudy :-)

Původní dotaz byl:

couda napsal(a):

Zdravím Vás,

Na novém projektu jsem se rozhodl, že vyzkouším Vaší knihovnu nittro.js a zatím jsem s ní nadmíru spokojen a překvapen, jak je s ní vše najednou daleko jednodušší.

Narazil jsem však na problém a nemohu se dopátrat nikde řešení – i když jsem ho někde zahlídl při hledání něčeho jiného, ani za zlaté prase se toho nemohu dohledat znovu.

Jde mi to, že jsem si udělal jednoduchý script na refresh 1 snippetu přes page.openLink a při přechodu uživatele na jinou stránku mi tento script stále běží i když s chybovou hláškou.

Je nějaká elegantní cesta, jak při přechodu uživatele mimo stránku stopnout tento automatický script?

díky

S pozdravem

David Štarman

Odpověď:

Zdravíčko,

no, takhle bez kontextu si nejsem jistý jak to přesně máte udělané, ale v obecné rovině jde o to rozhodnout se, který moment považujeme za „přechod na jinou stránku“, a v ten moment zrušit nějaký event handler nebo timer nebo jiný mechanismus, kterým tu aktualizaci spouštíte. V Nittru se dá navázat na událost before-update služby snippetManager, která se spouští vždy před aktualizací snippetů, které vrátila nějaká AJAXová odpověď; to by se (v souboru přibaleném na úplný konec Nittro buildu) implementovalo nějak takhle:

<script>
_context.invoke(function(di) {
    di.getService('snippetManager').on('before-update', function() {
        // spusti se pokazde kdyz se Nittro chysta updatovat snippety
        // po AJAXovem requestu (predtim nez se update aplikuje)
    });
});
</script>

Ale mnohem praktičtější je většinou svázat život JS widgetu s překreslováním nějakého konkrétního snippetu na stránce – pak se nemusíte po každém AJAX requestu rozhodovat, jestli se něco má stát nebo ne, prostě se to stane samo když se překreslí příslušný snippet. Zvlášť dobře to funguje když máte aplikaci hodně rozdělenou na komponenty. Implementace by v šabloně příslušné komponenty vypadala takhle:

<div n:snippet="mujSnippet">
    <!-- cokoliv -->

    <script type="application/javascript">
    _stack.push(function(di) {
        di.getService('page').getSnippet({snippetId mujSnippet})
            .setup(function() {
                // spusti se pri vykresleni snippetu
            })
            .teardown(function() {
                // spusti se tesne pred odstranenim snippetu
                // ze stranky nebo prekreslenim jeho obsahu
            });
    });
    </script>
</div>

Key points:

  • Co je to _context a _stack ?
  • {snippetId mujSnippet} je Latte macro poskytované composer balíčkem nittro/nette-bridges
  • Inline JS vs. CSP: stačí používat n:nonce, Nittro ho podporuje automaticky (popsáno na wiki v dokumentaci _stack viz odkaz výše)
  • Setup a teardown callbacky se spouští jen jednou – proto se jejich registrace dělá uvnitř snippetu – tím se zaregistrují a zpracují pokaždé, když se snippet objeví na stránce

Pomohlo? :-)

Hezký večer,
Dan Kadera