-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy path05s-the-session.md.erb
160 lines (108 loc) · 8.57 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
158
159
---
title: 세션(Session)
slug: the-session
date: 0005/01/02
number: 5.5
sidebar: true
contents: 미티어 세션에 대하여 배운다.|autorun 함수에 대하여 배운다.|Hot Code Reload에 대하여 배운다.
paragraphs: 33
---
미티어는 반응형 프레임워크이다. 이 의미는 데이터가 변경되면, 명시적으로 무슨 일을 하지 않고도 앱이 변경된다는 것이다.
우리는 데이터와 route가 변경될 때, 템플릿이 이에 따라서 변경되는 과정을 이미 본 적이 있다.
우리는 이것이 어떻게 작동하는지 나중에 더 깊이있게 살펴보기로 하고, 여기서는 일반적인 앱에서 특히 유용한 몇 가지 기본적인 반응형 특성에 대하여 소개하고자 한다.
### 미티어 세션
현재 Microscope에서는, 사용자 앱의 현재 상태는 URL(그리고 데이터베이스)에 모두 들어있다.
하지만 많은 경우에, 앱의 현재 사용자에게만 해당하는 일시적인 상태 정보(예를 들면, 어떤 엘리먼트가 보여지는 지, 숨겨지는 지)를 저장할 필요가 있다. 세션은 이런 것을 처리하는 데 편리한 방법이다.
세션은 전역 반응형 데이터 소스이다. 이것은 전역 싱글톤 객체라는 의미에서 전역적이다: 세션은 하나만 있고 어디서나 접근할 수 있다. 전역 변수는 일반적으로 나쁘게 보는 경향이 있지만, 이 경우에 세션은 앱의 여러 다른 파트와 소통하는 중심 통신 수단으로서 사용된다.
### 세션의 변경
세션은 어디에서나 `Session` 객체로 이용할 수 있다. 세션에 값을 저장하려면 아래와 같이 한다:
~~~js
❯ Session.set('pageTitle', 'A different title');
~~~
<%= caption "브라우저 콘솔" %>
세션에서 값을 읽을 때는 `Session.get('mySessionProperty');`로 한다. 이것은 반응형 데이터 소스이다. 이 의미는 만약 헬퍼에 이것을 넣으면, 세션 변수가 변경될 때 헬퍼의 출력값이 반응형으로 변경된다는 것이다.
직접 해보자. 아래와 같은 코드를 layout 템플릿에 추가한다:
~~~html
<header class="navbar">
<div class="navbar-inner">
<a class="brand" href="{{pathFor 'postsList'}}">{{pageTitle}}</a>
</div>
</header>
~~~
<%= caption "client/templates/application/layout.html"%>
~~~js
Template.layout.helpers({
pageTitle: function() { return Session.get('pageTitle'); }
});
~~~
<%= caption "client/templates/application/layout.js"%>
미티어의 (“hot code reload” 또는 HCR로 알려진) 자동 리로드는 세션 변수를 보존한다. 따라서, nav bar에서 “A different title”이 보일 것이다. 만약 보이지 않으면, 이전의 명령어인 `Session.set()`을 다시 한 번 입력하면 된다.
더욱이 우리가 그 값을 (브라우저 콘솔에서) 한 번 더 바꾸면, 바뀐 제목이 나타나는 것을 볼 수 있다:
~~~js
❯ Session.set('pageTitle', 'A brand new title');
~~~
<%= caption "브라우저 콘솔" %>
세션은 전역에서 이용할 수 있으므로, 앱의 어디에서나 이렇게 바꿀 수 있다. 이는 큰 힘이 되지만, 너무 많이 사용하면 함정이 될 수도 있다.
그런데, Session 객체가 이용자 사이에, 또는 심지어 브라우저의 탭사이에서 조차 공유되지 *않는다는* 점을 유의하는 것이 중요하다. 그래서 새로운 탭에서 앱을 열면, 사이트 타이틀이 빈 이유가 바로 여기에 있다.
<% note do %>
### 같은 값으로 변경
만약 세션 변수를 `Session.set()`으로 변경하되 동일한 값으로 변경하면, 미티어는 똑똑하게도 반응 체인에서 이를 그냥 건너뛰어 불필요한 함수 호출을 피한다.
<% end %>
### Autorun 소개
우리는 반응형 데이터 소스의 예제를 본 적이 있고, 템플릿 헬퍼의 내부에서 실제로 그것이 동작하는 것을 보았다. 그런데 미티어의 (템플릿 헬퍼 같은) 일부 컨텍스트는 태생부터 반응형이지만, 미티어의 앱 코드의 대부분은 여전히 전통적인 비-반응형 Javascript이다.
우리 앱의 일부에 아래와 같은 코드가 있다고 가정해보자:
~~~js
helloWorld = function() {
alert(Session.get('message'));
}
~~~
우리가 세션변수를 호출한다 해도, 이를 호출하는 *컨텍스트*는 반응형이 아니다. 이는 변수를 변경할 때마다 새로운 alert가 구동되는 것은 아니라는 의미이다.
여기에서 [Autorun](http://docs.meteor.com/#tracker_autorun)이 등장한다. 그 이름에서 의미하는 바와 같이, autorun 블럭의 내부의 코드는 자동적으로 실행이 되고 그 안에서 사용된 반응형 데이터 소스가 변경될 때마다 계속 실행된다.
아래 코드를 브라우저 콘솔에서 입력해보자:
~~~js
❯ Tracker.autorun( function() { console.log('Value is: ' + Session.get('pageTitle')); } );
Value is: A brand new title
~~~
<%= caption "브라우저 콘솔" %>
예상한대로, `autorun` 내부에 입력된 코드 블럭이 실행되고, 그 결과는 콘솔에 나타난다. 이제, 제목을 변경해보자:
~~~js
❯ Session.set('pageTitle', 'Yet another value');
Value is: Yet another value
~~~
<%= caption "브라우저 콘솔" %>
마술같다! 세션값이 변경되니, `autorun`이 이를 인지하고 그 내부의 내용을 모두 재실행하여 그 출력을 콘솔로 내보냈다.
따라서 이전 예제로 돌아가서, 세션변수가 변경될 때마다 경고가 구동되게 하려면, 우리가 할 일은 코드를 `autorun` 블럭에 넣는 것이다:
~~~js
Tracker.autorun(function() {
alert(Session.get('message'));
});
~~~
방금 본 바와 같이, autorun은 반응형 데이터 소스를 추적하고, 그것에 즉각 대응하는 데 매우 유용하다.
### Hot Code Reload
Microscope를 개발하는 동안, 우리는 개발 시간을 줄여주는 미티어의 다양한 기능들 중의 하나인 hot code reload(HCR)를 이용해왔다. 우리가 소스 코드 파일 중의 하나를 저장할 때마다, 미티어는 이를 감지하고 현재 실행중인 미티어 서버를 재실행하고 각 클라이언트에 해당 페이지를 다시 로드하도록 통지한다.
이것은 페이지의 자동 리로드와 비슷하지만 중요한 차이점이 있다.
그것이 무엇인지를 알기 위해서, 우리가 사용한 세션 변수를 리셋해보자:
~~~js
❯ Session.set('pageTitle', 'A brand new title');
❯ Session.get('pageTitle');
'A brand new title'
~~~
<%= caption "브라우저 콘솔" %>
만약 브라우저 창을 수동으로 리로드하면, 세션 변수는 자연적으로 소멸될 것이다(이렇게 하면 새로운 세션이 생성되기 때문이다). 반면에 hot code reload 기능을 구동하면 (예를들면, 소스파일의 일부를 저장하여), 페이지는 리로드되지만 세션변수는 여전히 값을 유지할 것이다. 지금 해보라!
~~~js
❯ Session.get('pageTitle');
'A brand new title'
~~~
<%= caption "브라우저 콘솔" %>
그러므로, 사용자가 하는 일을 정확하게 추적하는 데 세션 변수를 사용한다면, 사용자는 HCR을 거의 느끼지 못할 것이다. 왜냐면 이것은 모든 세션변수의 값을 보존할 것이기 때문이다. 따라서 우리는 미티어 앱의 새 버전의 제품을 배포할 때, 사용자에게 지장을 최소화할 것이라는 확신을 가진다.
잠깐 이에 대하여 숙고해보자. 우리가 URL와 세션에 모든 상태값을 저장하게 되면, 각 클라이언트 앱의 _실행중인 소스코드_를 최소한의 지장을 주는 수준에서 사용자가 느끼지 못하게 변경할 수 있다.
이제 페이지를 수동으로 갱신할 때 무슨 일이 일어나는지 살펴보자:
~~~js
❯ Session.get('pageTitle');
null
~~~
<%= caption "브라우저 콘솔" %>
페이지가 리로드되면, 세션 정보는 사라진다. HCR의 경우, 미티어는 세션을 브라우저의 로컬 저장소에 저장하며, 리로드 후에 그것을 다시 읽어들인다. 그런데, 수동 리로드에서의 이 다른 행태는 이해가 된다: 사용자가 페이지를 리로드하면, 그것은 사용자가 동일한 URL로 브라우징을 다시 한 것으로 인식한다. 그래서 세션 정보는 사용자가 해당 URL을 방문할 때 보는 초기상태로 리셋된다.
이 모두에서 얻는 중요한 가르침은 다음과 같다:
1. HCR이 일어날 때 사용자가 받는 영향을 최소화하도록 항상 사용자 상태를 세션이나 URL에 저장하라.
2. 사용자들 사이에 공유되기를 원하는 상태가 있다면 이를 *URL에 저장하라*.