接續昨天的內容,要怎麼做才可以讓資料庫同時具有 persistence 與 reactivity 呢?
首先我們建立 server
資料夾,並且新增一個檔案:
// my-app/server/todos.js
import { Mongo } from 'meteor/mongo';
const Todos = new Mongo.Collection('todos');
export default Todos;
並且確認在 client
資料夾也有一個同樣的檔案。
在 Day01:初探 Meteor 的最後有提到,放在 server
資料夾底下的檔案會被載入到伺服器端,而放在 client
資料夾底下的檔案會載入到瀏覽器端,因此現在瀏覽器和伺服器端都有了一個叫做 Todos 的 collection。
這邊要特別注意在這兩個檔案中 Mongo.Collection()
的括號裡頭要放入相同的字串,一般來說會放 collection 的名稱,這樣子在瀏覽器端呼叫 insert
, update
, remove
就會直接對伺服器端的資料庫進行操作。
現在我們一樣在昨天寫好的輸入框輸入文字並且按下 enter...咦?為什麼資料不會自動顯示了?我們打開瀏覽器發開者工具的 console 會看到一行錯誤訊息:insert failed: Access denied
,要解決這個問題只要加入 insecure
套件即可,在 terminal 輸入 meteor add insecure
。
我們再試一次輸入文字並且按下 enter...咦?還是不會顯示?其實資料已經存到資料庫了,但在瀏覽器端呼叫 find
時並不會就會直接讀取伺服器端的資料庫,而是讀取瀏覽器端的 Minimongo,我們需要使用 publish/subscribe 的機制把伺服器端的資料庫同步到瀏覽器端。
在伺服器端透過 Meteor.publish(資料集名稱, function)
來定義準備要送到瀏覽器端的資料集,function 必須回傳 Collection.Cursor
,而在瀏覽器端可以透過 Meteor.subscribe(資料集名稱)
來接收相同名稱的資料集並且儲存到 Minimongo。作法如下:
在 server
資料夾底下新增一個檔案:
// my-app/server/publications.js
import { Meteor } from 'meteor/meteor' // 引入 Meteor 核心套件
import Todos from './todos'
Meteor.publish('todos', () => {
return Todos.find({});
});
//
並且修改 hello.js
:
// my-app/client/hello.js
import { Meteor } from 'meteor/meteor'; // 引入 Meteor 核心套件
import { Template } from 'meteor/templating';
import Todos from './todos';
Template.hello.onCreated(function() {
// 加入以下程式碼
Meteor.subscribe('todos');
// 以上
});
經過以上修改,之前存進去的資料就會顯示在頁面上,我們勇敢的再試一次輸入文字並且按下 enter...存入的資料馬上顯示囉!等等!我們剛剛加入了 insecure
套件,顧名思義這個套件是"insecure"的...沒錯!Meteor 本身是不允許使用者直接從瀏覽器端對資料庫進行存取的,但提供了 insecure
套件讓開發者在開發 prototype 時移除掉這個限制,在下一章節我們會把這個套件移除,並且使用更安全的方式來存取資料庫。