-
Notifications
You must be signed in to change notification settings - Fork 9
/
04-collections.md.erb
335 lines (216 loc) · 9.32 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: Koleksi
slug: collections
date: 0004/01/01
number: 4
contents: Belajar mengenai fitur inti Meteor, koleksi realtime.|Mengerti bagaimana sinkronisasi data Meteor bekerja.|Mengintegrasi koleksi dengan templat.|Mengubah prototipe dasar menjadi aplikasi realtime yang fungsional!
paragraphs: 72
---
Pada bab satu, kita membahas fitur inti Meteor, sinkronisasi otomatis data antar klien dan server.
Pada bab ini, kita akan menggali lebih dalam bagaiamana caranya bekerja dan mengamati operasi teknologi pendukungnya, yaitu Koleksi Meteor.
Kita sedang membangun aplikasi berita sosial, jadi hal pertama yang hendak kita lakukan adalah membuat daftar tautan yang dilansir. Kita akan menyebut masing-masingnya sebagai "lansiran."
Tentunya, kita perlu menyimpan lansiran ini disuatu tempat. Meteor hadir terbundel bersama database Mongo yang berjalan diatas server dan menjadi tempat penyimpan data *tetap*.
Jadi, kendati peramban pengguna berada pada suatu jenis keadaan (misalnya tengan berada pada halaman mana atau tengah mengetik komentar), server dan khususnya Mongo, menyimpan sumber data resmi yang tetap. *Resmi* disini artinya sama untuk semua pengguna: tiap pengguna bisa jadi berada pada halaman berbeda, namun daftar induk lansiran adalah sama untuk semua.
Data ini tersimpan di dalam **Koleksi** Meteor. Koleksi merupakan struktur data khusus, melalui penerbitan dan langganan, memelihara kerampakkan data waktu-nyata dari masing-masing peramban pengguna ke basis data Mongo dan sebaliknya. Mari lihat bagaimananya.
Kita ingin lansiran kita menjadi permanen dan terbagikan antar pengguna, jadi kita akan memulai dengan membuat koleksi disebut `Posts` sebagai wadah simpan. Buatlah direktori `collections/` pada direktori akar aplikasimu dan berkas `posts.js` di dalamnya. Kemudian tambahkan:
~~~js
Posts = new Meteor.Collection('posts');
~~~
<%= caption "collections/posts.js" %>
<%= commit "4-1", "Ditambahkan koleksi posts" %>
Kode di luar direktori `client/` dan `server/` akan berjalan pada dua konteks. Jadi koleksi `Posts` tersedia baik untuk klien maupun server. Bagaimanapun, apa yang koleksi lakukan untuk masing-masing lingkungan amat lah berbeda.
<% note do %>
### Var atau Bukan Var?
Dalam Meteor, kata-kunci `var` membatasi lingkup obyek hanya pada berkas saat ini. Sementara kita ingin membuat koleksi `Posts` tersedia untuk keseluruhan aplikasi, itu sebabnya mengapa kita tak menggunakan kata-kunci `var`.
<% end %>
Pada server, koleksi memiliki tugas berkomunikasi kepada basis-data Mongo dan membaca dan menulis setiap perubahan. Sebanding dengan kerja pustaka basis-data umumnya. Pada klien, koleksi menjadi salinan *aman* data sesungguhnya.
<% note do %>
### Konsol vs Konsol vs Konsol
In this chapter, we'll start making use of the **browser console**, which is not to be confused with the **terminal** or the **Mongo shell**. Here's a quick primer on each of them.
Dalam bab ini kita akan mulai menggunakan **konsol peramban**, harap tidak menyalah artikannya dengan **terminal** atau **shell Mongo**. Berikut perbedaannya.
#### Terminal
<%= screenshot "terminal", "Terminal" %>
- Dijalankan dari sistem operasi.
- **sisi-server** `console.log()` memanggil keluaran disini.
- Prompt: `$`.
- Juga dikenal sebagai: Shell, Bash
#### Konsol Peramban
<%= screenshot "browser-console", "Konsol peramban" %>
- Dijalankan dari peramban, eksekusi kode JavaScript.
- **Sisi klien** `console.log()` memanggil keluaran disini.
- Prompt: `❯`.
- Juga dikenal sebagai: Konsol JavaScript, Konsol DevTools
#### Shell Mongo
<%= screenshot "mongo-shell", "Shell Mongo" %>
- Dijalankan dari terminal dengan perintah `meteor mongo` atau `mrt mongo`.
- Gives you direct access to your app's database.
- Prompt: `>`.
- Juga dikenal sebagai: Konsol Mongo
Perlu dicatat, kamu tak seharusnya mengetikkan karakter-karakter prompt (`$`, `❯`, or `>`) sebagai bagian dari perintah. Dan setiap baris yang tak diawali dengan prompt merupakan keluaran dari perintah yang dieksekusi.
<% end %>
### Koleksi Sisi-Server
Pada sisi-server, koleksi berperan sebagai API basis-data Mongo. Hal ini memungkinkan kamu menulis perintah Mongo seperti `Posts.insert()` atau `Posts.update()`, dan melakukan perubahan pada koleksi `posts` yang tersimpan di dalam Mongo.
Untuk melihat kedalam basis-data Mongo, buka lah jendela terminal kedua (sementara `meteor` masih berjalan dijendela pertama) dan kunjungi direktori aplikasi kamu. Kemudian, jalankan perintah `meteor mongo` untuk memulai shell Mongo, dimana kamu bisa mengetikkan perintah Mongo baku (dan seperti biasa, kamu bisa menghentikannya dengan tombol `ctrl+c` pada keyboard). Sebagai contoh, mari masukkan lansir baru:
~~~bash
> db.posts.insert({title: "A new post"});
> db.posts.find();
{ "_id": ObjectId(".."), "title" : "A new post"};
~~~
<%= caption "Shell Mongo" %>
<% note do %>
### Mongo pada Meteor.com
Perlu dicatat bahwa ketika menyimpan (hosting) aplikasi kamu di *.meteor.com, kamu juga bisa mengakses shell Mongo dengan `meteor mongo myApp`.
Dan ketika kita berada di situ, kamu juga bisa mendapatkan log aplikasi dengan perintah `meteor logs myApp`.
<% end %>
Sintaks Mongo itu familiar karena menggunakan antarmuka JavaScript. Kita tak akan melakukan manipulasi data lebih lanjut di dalam shell Mongo, kendati boleh juga sesekali mengamatinya sekedar memastikan apa yang ada di dalam.
### Koleksi Sisi-Klien
Koleksi mendapatkan sisi-klien yang lebih menarik. Ketika kamu menyatakan `Posts = new Meteor.Collection('posts');` pada klien, apa yang tengah kamu buat adalah _local, cache_ bawaan peramban koleksi Mongo.
Penting untuk mengetahui hal ini mengingat sangat mendasar bagi cara kerja Meteor. Secara umum, koleksi sisi-klien terdiri dari bagian-bagian dokumen yang tersimpan di dalam koleksi Mongo (lagi pula, kita biasanya tak ingin mengirim keseluruhan isi basis-data kepada klien).
Kedua, dokumen-dokumen tersebut tersimpan *dalam memori peramban*, yang berarti mengaksesnya akan menjadi lebih cepat. Jadi tak ada lalu lintas lambat menuju server atau basis-data guna mengambil data ketika memanggil `Posts.find()` pada klien, karena data telah dimuat.
<% note do %>
### Memperkenalkan MiniMongo
Pelaksanaan Mongo sisi-klien pada Meteor disebut MiniMongo. Pelaksanaan ini belum lah sempurna dan sesekali kamu akan menjumpai fitur-fitur Mongo yang tak bekerja pada MiniMongo. Kendati demikian, keseluruhan fitur yang kita cakup dalam buku ini bekerja persis sama untuk keduanya (Mongo dan MiniMongo).
<% end %>
### Komunikasi Klien-Server
Kunci dari semua ini adalah bagaimana koleksi sisi-klien dan koleksi sisi-server dengan nama yang sama (dalam hal ini `'posts'`) bisa menyerempakkan datanya.
Ketimbang menjelaskan hal ini secara detil, lebih baik kita saksikan saja apa yang terjadi.
Mari mulai dengan membuka dua jendela peramban dan mengakses konsolnya masing-masing. Kemudian, buka shell Mongo dengan baris perintah. Pada tahap ini, kita seharusnya dapat melihat dokumen yang kita buat sebelumnya.
~~~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
////