forked from DiscoverMeteor/DiscoverMeteor_Pt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path04-collections.md.erb
335 lines (216 loc) · 9.28 KB
/
04-collections.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
---
title: Coleções
slug: collections
date: 0004/01/01
number: 4
contents: Aprenda sobre a principal característica do Meteor, coleções em tempo real.|Entenda como a sincronização de dados funciona no Meteor.|Integre coleções com seus templates.|Transforme nosso protótipo basico em uma aplicação funcional em tempo real!
paragraphs: 72
---
No primeiro capítulo nós falamos sobre a principal característica do Meteor, a sincronização automatica de dados entre cliente e servidor.
Nesse capítulo nós vamos olhar de perto como isso funciona e observar a principal peça de tecnologia que permite isso, Coleções do Meteor.
Nós estamos construindo uma aplicação de rede social de notícias, então a primeira coisa que queremos fazer é uma lista de links que pessoas postaram. Nós vamos chamar cada um desses itens de "artigo".
Naturalmente, nós precisamos guardar esses artigos em algum lugar. O Meteor vem com o banco de dados MongoDB integrado, ele roda em seu servidor e guarda dados *persistentes*.
Então, apesar do browser/navegador do usuário poder conter algum tipo de estado(por exemplo que página ele está ou o commentário que está digitando), o servidor, especificamente o MongoDB, contém os dados permanentes e canonicais. Por *canonical* nos referimos que é o mesmo para todos usuários, cada usuário pode estar em uma página diferente, mas a lista principal de artigos é a mesma para todos.
Esses dados são armazenados no Meteor em **Coleções**. Uma coleção é uma estrutura especial de dados que através de publicações e subscricões, é responsável pelo sincronismo de dados em tempo real para e de cada browser do usuário conectado no banco de dados Mongo. Vamos ver como.
Nós queremos nossos artigos sejam permanentes e que todos usuários possam ver, então vamos começar criando uma coleção chamada `Posts` para armazenar os artigos. Se você ainda não criou uma pasta `collections/` na pasta principal crie e depois o arquivo `posts.js` dentro da pasta `collections/`.
~~~js
Posts = new Meteor.Collection('posts');
~~~
<%= caption "collections/posts.js" %>
<%= commit "4-1", "Added a posts collection" %>
Código dentro das pastas que não são `client/` e `server/` vão rodar `nos dois` contextos. Então a coleção `Posts` é disponível tanto no cliente como no servidor. Entretanto, o que a coleção faz em cada ambiente é bem diferente.
<% note do %>
### To Var Or Not To Var?
Em Meteor, a palavra-chave `var` limita o escopo de um objeto para somente aquele arquivo. Nós queremos fazer a coleção `Posts` disponível para toda nossa aplicação, e por isso estamos omitindo a palavra-chave aqui.
<% end %>
No servidor, a coleção tem o trabalho de se comunicar com o banco de dados Mongo, ler e escrever quaisquer mudanças. Nesse sentido, pode ser comparada com um banco de dados de uma biblioteca padrão. No cliente entretando, a coleção é uma copia *segura* the um *subsistema* da coleção real canônica. A coleção do lado do cliente é atualizada constantemente e (na maioria das vezes)
transparentemente com aquele subsistema da coleção em tempo real.
<% note do %>
### Console vs Console vs Console
Nesse capítulo nós vamos começar a usar o **console do navegador**, o qual não pode ser confundido com o **terminal** ou o **Mongo shell**. Veja uma introdução de cada um deles.
#### Terminal
<%= screenshot "terminal", "The Terminal" %>
- Chamado de seu sistema operacional
- **Lado do Servidor** `console.log()` chama o resultado aqui.
- Prompt de commando:`$`.
- Também conhecido como: Shell Bash
#### Console do Navegador
<%= screenshot "browser-console", "The Browser Console" %>
- Chamado de dentro de seu navegador, executa código Javascript.
- **Lado do Cliente** `console.log()` chama o resultado aqui.
- Prompt: `>`.
- Também conhecido como: Javascript Console, DevTools Console
#### Mongo Shell
<%= screenshot "mongo-shell", "The Mongo Shell" %>
- Chamado do Terminal com `meteor mongo` ou `mrt mongo`.
- Dá acesso ao banco de dados da aplicação.
- Prompt:`>`.
- Também conhecido como: Mongo Console
Note que em cada caso, você não deve digitar o caracter do prompt (`$`, `❯`, ou `>`) como parte do comando. E você pode assumir que qualquer linha que *não* comece com caracter do prompt é o resultado do comando anterior.
<% end %>
### Server-Side Collections
No lado do servidor, a coleção atua como uma API em seu banco de dados Mongo. Em seu código do lado do servidor isso permite que você escreva comandos Mongo como `Posts.insert()` ou `Posts.update()`, e eles vão fazer mudanças na coleção `posts` armazenada dentro do Mongo.
Para ver dentro do banco de dados Mongo, abra uma segunda janela do terminal (enquanto `meteor` ainda está rodando na primeira janela), e acesse a pasta de sua aplicação (pelo terminal). Então rode o comando `meteor mongo` para iniciar o Mongo Shell, dentro do terminal você pode digitar Mongo commandos padrões (como sempre, você pode sair com `ctrl+c` atalho do teclado). Por exemplo vamos inserir um novo artigo:
~~~bash
> db.posts.insert({titulo: "Um novo artigo"});
> db.posts.find();
{ "_id": ObjectId(".."), "titulo" : "Um novo artigo"};
~~~
<%= caption "The Mongo Shell" %>
<% note do %>
### Mongo on Meteor.com
Note que quando você hospedar sua aplicação em *.meteor.com, você também pode acessar o Mongo shell com `meteor mongo minhaApp`.
E enquanto nós estivermos nisso, você pode também ver logs da aplicação escrevendo `meteor logs minhaApp`.
<% end %>
A sintaxe do Mongo é familiar, já que utiliza a interface Javascript. Nós não vamos muito longe na manipulação de dados no Mongo shell, mas vamos dar uma olhada de tempos em tempos só para ver se tudo está certo por lá.
### Coleções do Lado do Cliente
Coleções ficam mais interessantes do lado do cliente. Quando você declara `Posts = new Meteor.Collection('posts');` no cliente, o que você está criando é um _local, no browser cache_ de uma coleção Mongo real. Quando falamos sobre coleções do lado-cliente sendo um "cache", nós nos referimos no senso de que ele contém um *subsistema* de seus dados e oferece um acesso muito *rápido* a esses dados.
É importante entender esse ponto pois é fundamental para entender como o Meteor funciona. Em geral, uma coleção do lado do servidor consiste em um subsistema de todos os documentos armazenados em uma coleção Mongo (afinal das contas, não queremos enviar *todo* nosso banco de dados para o cliente).
Esses documentos também são armazenados *na memória do browser* o que significa que acessá-los é basicamente instantaneamente. Então não ocorrem viagens lentas do servidor ou banco de dados para buscar os dados quando você chama `Posts.find()` no cliente, porque os dados já são previamente carregados.
<% note do %>
### Introducing MiniMongo
////
<% end %>
### Client-Server Communication
////
////
////
~~~bash
> db.posts.find();
{title: "A new post", _id: ObjectId("..")};
~~~
<%= caption "The Mongo Shell" %>
~~~js
❯ Posts.findOne();
{title: "A new post", _id: LocalCollection._ObjectID};
~~~
<%= caption "First browser console" %>
////
~~~js
❯ Posts.find().count();
1
❯ Posts.insert({title: "A second post"});
'xxx'
❯ Posts.find().count();
2
~~~
<%= caption "First browser console" %>
////
~~~bash
❯ db.posts.find();
{title: "A new post", _id: ObjectId("..")};
{title: "A second post", _id: 'yyy'};
~~~
<%= caption "The Mongo Shell" %>
////
////
~~~js
❯ Posts.find().count();
2
~~~
<%= caption "Second browser console" %>
////
////
////
### Keeping it Real-time
////
////
### Populating the Database
////
////
////
~~~bash
$ meteor reset
~~~
////
////
~~~js
if (Posts.find().count() === 0) {
Posts.insert({
title: 'Introducing Telescope',
author: 'Sacha Greif',
url: 'http://sachagreif.com/introducing-telescope/'
});
Posts.insert({
title: 'Meteor',
author: 'Tom Coleman',
url: 'http://meteor.com'
});
Posts.insert({
title: 'The Meteor Book',
author: 'Tom Coleman',
url: 'http://themeteorbook.com'
});
}
~~~
<%= caption "server/fixtures.js" %>
<%= commit "4-2", "Added data to the posts collection." %>
////
////
### Wiring the data to our HTML with helpers
////
~~~js
❯ Posts.find().fetch();
~~~
<%= caption "Browser console" %>
////
////
~~~js
Template.postsList.helpers({
posts: function() {
return Posts.find();
}
});
~~~
<%= caption "client/views/posts/posts_list.js" %>
<%= highlight "2~4" %>
<%= commit "4-3", "Wired collection into `postsList` template." %>
<% note do %>
### Find & Fetch
////
////
<% end %>
////
<%= screenshot "4-3", "Using live data" %>
////
////
~~~js
❯ Posts.insert({
title: 'Meteor Docs',
author: 'Tom Coleman',
url: 'http://docs.meteor.com'
});
~~~
<%= caption "Browser console" %>
////
<%= screenshot "4-4", "Adding posts via the console" %>
////
<% note do %>
### Inspecting DOM Changes
////
////
<% end %>
### Connecting Collections: Publications and Subscriptions
////
////
~~~bash
$ meteor remove autopublish
~~~
////
////
////
~~~js
Meteor.publish('posts', function() {
return Posts.find();
});
~~~
<%= caption "server/publications.js" %>
////
~~~js
Meteor.subscribe('posts');
~~~
<%= caption "client/main.js" %>
<%= commit "4-4", "Removed `autopublish` and set up a basic publication." %>
////
### Conclusion
////