Le variabili in Session

Approfondimento 5.5

Percentuale Tradotta

In questo capitolo imparerai:

  • L'oggetto Session in Meteor
  • La funzione autorun
  • Il ricaricamento a caldo del codice
  • Meteor è un framework reattivo. Ciò significa che al variare dei dati la nostra applicazione si aggiorna senza la necessità di fare nulla di specifico.

    Abbiamo già visto all'opera questo meccanismo sui template che si aggiornano al variare dei dati e delle route.

    Approfondiremo questo meccanismo nei prossimi capitoli, ma ora vogliamo introdurre alcune caratteristiche reattive di base usate spesso nelle applicazioni.

    L'oggetto Session in Meteor

    In questo momento in Microscope lo stato dell'applicazione è interamente contenuto nell'URL che l'utente sta consultando (e nel database).

    In molti casi però hai bisogno di alcune informazioni transitorie sullo stato dell'applicazione, rilevanti solo per l'istanza corrente dell'applicazione di uno specifico utente (ad esempio se un elemento è mostrato o nascosto). L'oggetto Session è perfetto per questo.

    L'oggetto Session è un contenitore dati globale e reattivo. È globale nel senso di un unico oggetto visibile ovunque: c'è una sola sessione ed è accessibile dall'intera applicazione. Le variabili globali sono normalmente mal viste ma in questo caso l'oggetto Session è usato come centro di comunicazione tra tutte le parti dell'applicazione.

    Memorizzare dati nell'oggetto Session

    L'oggetto sessione è visibile ovunque come Session. Per impostare un valore si invoca:

     Session.set('pageTitle', 'A different title');
    
    Browser console

    I dati memorizzati posso essere letti con Session.get('mySessionProperty');. È una sorgente dati reattiva, quindi se utilizzata all'interno di un helper vedremo l'output dell'helper modificarsi automaticamente al cambio dei dati.

    Per fare una prova, aggiungi questo codice al template di layout:

    <header class="navbar">
      <div class="navbar-inner">
        <a class="brand" href="{{pathFor 'postsList'}}">{{pageTitle}}</a>
      </div>
    </header>
    
    client/views/application/layout.html
    Template.layout.helpers({
      pageTitle: function() { return Session.get('pageTitle'); }
    });
    
    client/views/application/layout.js

    Il meccanismo di ricaricamento automatico del codice di Meteor (noto come “hot code reload” o HCR) preserva lo stato delle variabili di sessione, e quindi ora dovremmo vedere “A different title” nella barra di navigazione. Se no occorre ridigitare il comando Session.set() di nuovo.

    Inoltre se cambiamo ancora una volta il valore (nuovamente nella console del browser), vedremo il nuovo titolo:

     Session.set('pageTitle', 'A brand new title');
    
    Browser console

    L'oggetto Session è visibile globalmente, quindi le variazioni possono essere fatte ovunque nell'applicazione. Questo ci apre molte possibilità ma può anche trasformarsi in una trappola, se ne abusiamo.

    Modifiche Identiche

    Se modifichi una variabile della sessione con Session.set() reimpostando il valore già memorizzato, Meteor è sufficientemente intelligente da non eseguire alcun aggiornamento reattivo, evitando inutili elaborazioni.

    Introduciamo Autorun

    Abbiamo visto un esempio di sorgente dati reattiva e visto il suo impiego all'interno di un helper. Dobbiamo però tenere presente che sebbene alcuni contesti in Meteor siano intrinsecamente reattivi (come gli helper dei template), la maggior parte di una applicazione Meteor è puro e semplice JavaScript non reattivo.

    Supponiamo di avere questo codice nell'applicazione:

    helloWorld = function() {
      alert(Session.get('message'));
    }
    

    Anche se stiamo utilizzando una variabile di sessione, il contesto in cui viene usata non è reattivo, e dunque non saranno mostrati nuovi alert ogni volta che modifichiamo la variabile.

    È in queste circostanze che torna utile Autorun. Come dice il nome stesso, il codice all'interno di un blocco autorun sarà eseguito e rieseguito ogni volta che le sorgenti dati reattive all'interno vengono modificate.

    Scriviamo nella console del browser:

     Deps.autorun( function() { console.log('Value is: ' + Session.get('pageTitle')); } );
    Value is: A brand new title
    
    Browser console

    Come ci saremmo aspettati il codice all'interno di autorun è stato eseguito mostrando l'output in console. Ora proviamo a modificare il titolo:

     Session.set('pageTitle', 'Yet another value');
    Value is: Yet another value
    
    Browser console

    Magia! Al variare del valore di sessione autorun sapeva di dover rieseguire il codice, ristampando il nuovo valore nella console.

    Dunque tornando al nostro esempio di prima, se vogliamo produrre un alert ogni volta che la variabile di sessione cambia dobbiamo inserire il codice in un blocco autorun:

    Deps.autorun(function() {
      alert(Session.get('message'));
    });
    

    Come abbiamo appena visto l'autorun del codice è molto utile per monitorare i dati reattivi e agire al loro variare.

    Hot Code Reload

    Durante lo sviluppo di Microscope abbiamo usato una delle caratteristiche di Meteor che fanno risparmiare tempo: il ricaricamento a caldo del codice (hot code reload, HCR). Ogni volta che salviamo un file sorgente, Meteor se ne accorge e riavvia il server in maniera trasparente, informando ogni client che è necessario ricaricare la pagina.

    Questo meccanismo è simile al ricaricamento automatico della pagina, ma con una importante differenza.

    Per capire quale, azzeriamo la variabile di sessione che abbiamo usato finora:

     Session.set('pageTitle', 'A brand new title');
     Session.get('pageTitle');
    'A brand new title'
    
    Browser console

    Se ricaricassimo la pagina nella finestra del browser manualmente, le variabili contenute nell'oggetto Session andrebbero perse (in quanto si creerebbe un'intera nuova sessione). Invece quando modifichiamo e salviamo un sorgente scatenando un ricaricamento a caldo del codice, la variabile di sessione non perde il suo valore. Proviamo!

     Session.get('pageTitle');
    'A brand new title'
    
    Browser console

    Questo significa che se stiamo usando le variabili di sessione per tenere traccia di cosa sta facendo l'utente, il ricaricamento a caldo sarà trasparente per l'utente, perché il valore delle variabili di sessione rimane inalterato. Possiamo quindi rilasciare nuove versioni di una applicazione Meteor ed aspettarci che gli utenti ne saranno solo minimamente disturbati.

    Pensaci un attimo. Se possiamo gestire tutto lo stato tramite URL e sessione, possiamo modificare in maniera trasparente il codice in esecuzione di ogni applicazione sotto il naso dell'utente mentre è in esecuzione e con problemi minimi.

    Vediamo invece cosa succede se facciamo manualmente il refresh della pagina:

     Session.get('pageTitle');
    null
    
    Browser console

    Al ricaricamento della pagina abbiamo perso la sessione. Durante un HCR, Meteor memorizza la sessione nel browser e la recupera dopo il reload. D'altro canto il normale comportamento al ricaricamento della pagina ha senso: se un utente ricarica esplicitamente una pagina è come se avesse raggiunto quell'URL per la prima volta, e quindi tutto deve apparire nello stesso stato iniziale che qualsiasi altro utente troverebbe raggiungendo quell'URL.

    Queste sono le importanti lezioni di tutto questo:

    1. Memorizza sempre lo stato dell'utente nell'oggetto Session oppure nell'URL così da minimizzare i problemi degli utenti in caso di HCR.
    2. Memorizza qualsiasi informazione di stato che si desidera sia condivisibile con altri utenti dentro l'URL stessa.