-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy path05s-the-session.md.erb
157 lines (107 loc) · 7.67 KB
/
05s-the-session.md.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
---
title: Le variabili in Session
slug: the-session
date: 0005/01/02
number: 5.5
sidebar: true
contents: L'oggetto Session in Meteor|La funzione autorun|Il ricaricamento a caldo del codice
paragraphs: 33
---
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:
~~~js
❯ Session.set('pageTitle', 'A different title');
~~~
<%= caption "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:
~~~html
<header class="navbar">
<div class="navbar-inner">
<a class="brand" href="{{pathFor 'postsList'}}">{{pageTitle}}</a>
</div>
</header>
~~~
<%= caption "client/views/application/layout.html"%>
~~~js
Template.layout.helpers({
pageTitle: function() { return Session.get('pageTitle'); }
});
~~~
<%= caption "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:
~~~js
❯ Session.set('pageTitle', 'A brand new title');
~~~
<%= caption "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.
<% note do %>
### 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.
<% end %>
### 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:
~~~js
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](http://docs.meteor.com/#deps_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:
~~~js
❯ Deps.autorun( function() { console.log('Value is: ' + Session.get('pageTitle')); } );
Value is: A brand new title
~~~
<%= caption "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:
~~~js
❯ Session.set('pageTitle', 'Yet another value');
Value is: Yet another value
~~~
<%= caption "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`:
~~~js
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:
~~~js
❯ Session.set('pageTitle', 'A brand new title');
❯ Session.get('pageTitle');
'A brand new title'
~~~
<%= caption "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!
~~~js
❯ Session.get('pageTitle');
'A brand new title'
~~~
<%= caption "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:
~~~js
❯ Session.get('pageTitle');
null
~~~
<%= caption "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*.