iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 6
0

MongoDB 為 Meteor 預設連接的資料庫,透過 Collection 來存取,但 Collection 不僅僅提供儲存與讀取資料等基本功能,還擁有 reactivity 的特性,進一步優化使用者體驗。為了實現 reactivity,資料庫可以同時存在於伺服器端與瀏覽器端。什麼?瀏覽器也有資料庫?沒錯!以下會進一步說明。

建立 collection

client 建立一個 Todos 的資料表,也就是 MongoDB 的 collection:

// my-app/client/todos.js
import { Mongo } from 'meteor/mongo';

const Todos = new Mongo.Collection();

export default Todos;

然後在 hello.js 中 import 這個 collection:

// my-app/client/hello.js
import Todos from './todos';

Meteor 的 Minimongo 套件實作了 MongoDB API,讓我們可以在 client 端建立一個 in-memory 的資料庫,並且對這個資料庫進行存取,還同時具有 reactivity 的效果。

新增 document

MongoDB 的每一筆資料稱為 document,新增一筆 document 的方法很簡單:collection名稱.insert(document內容),而 document 內容其實就是一個 object。

我們試著建立一個輸入框,並且在按下 enter 時,將輸入框內的文字存成一筆資料,也就是 MongoDB 的 document,作法如下:

<!-- my-app/client/hello.html -->
<template name="hello">
	<input type="text" id="myInput">
</template>
// my-app/client/hello.js
Template.hello.events({
	'keyup #myInput'(event, templateInstance) {
		if (event.keyCode === 13) {
			Todos.insert({
				text: event.currentTarget.value,
				date: new Date(),
			});
			event.currentTarget.value = '';
		}
	},
});

不過我們現在還看不到存進資料庫的內容,接下來介紹如何讀取資料並且顯示。

讀取 document

讀取 document 的方法:collection名稱.find(selector),會回傳具有 reactivity 的 Collection.Cursor,可以直接在模板中使用,其中 selector 是一個 object,用法請參考collections#selectors

這邊我們試著將從輸入框存進去的資料全部顯示出來,只要資料庫的資料有任何變動,畫面都會呈現最新的資料。

<!-- my-app/client/hello.html -->
<template name="hello">
	<input type="text" id="myInput">
    <!-- 加入以下程式碼 -->
    <ul>
        {{#each todos}}
        <li>
            {{text}} - {{date}}
        </li>
        {{/each}}
    </ul>
    <!-- 以上 -->
</template>
// my-app/client/hello.js
Template.hello.events({
	'keyup #myInput'(event, templateInstance) {
		if (event.keyCode === 13) {  // enter 的 keycode 是 13
			Todos.insert({
				text: event.currentTarget.value,
				date: new Date(),
			});
			event.currentTarget.value = '';
		}
	},
});

// 加入以下程式碼
Template.hello.helpers({
	todos() {
		return Todos.find({});
	},
});
// 以上

更新 document

更新 document 的方法:collection名稱.update(selector, modifier),modifier 也是一個 object,用法請參考collections#modifiers

我們新增一個可以更新時間的按鈕:

<!-- my-app/client/hello.html -->
<template name="hello">
	<input type="text" id="myInput">
    <ul>
        {{#each todos}}
        <li>
            {{text}} - {{date}}
            <!-- 加入以下程式碼 -->
            <button class="updateButton">更新時間</button>
            <!-- 以上 -->
        </li>
        {{/each}}
    </ul>
</template>
// my-app/client/hello.js
Template.hello.events({
	'keyup #myInput'(event, templateInstance) {
		if (event.keyCode === 13) {
			Todos.insert({
				text: event.currentTarget.value,
				date: new Date(),
			});
			event.currentTarget.value = '';
		}
	},
    // 加入以下程式碼
    'click .updateButton'(event, templateInstance) {
        Todos.update({
        	_id: this._id,  // this 參考到該筆 document
        }, {
        	$set: { date: new Date() },
        });
    },
    // 以上
});

Template.hello.helpers({
	todos() {
		return Todos.find({});
	},
});

刪除 document

刪除 document 的方法很簡單:collection名稱.remove(selector)

我們新增一個可以刪除的按鈕:

<!-- my-app/client/hello.html -->
<template name="hello">
	<input type="text" id="myInput">
    <ul>
        {{#each todos}}
        <li>
            {{text}} - {{date}}
            <button class="updateButton">更新時間</button>
            <!-- 加入以下程式碼 -->
            <button class="deleteButton">刪除</button>
            <!-- 以上 -->
        </li>
        {{/each}}
    </ul>
</template>
// my-app/client/hello.js
Template.hello.events({
	'keyup #myInput'(event, templateInstance) {
		if (event.keyCode === 13) {
			Todos.insert({
				text: event.currentTarget.value,
				date: new Date(),
			});
			event.currentTarget.value = '';
		}
	},
    'click .updateButton'(event, templateInstance) {
        Todos.update({
        	_id: this._id,  // this 參考到該筆 document
        }, {
        	$set: { date: new Date() },
        });
    },
    // 加入以下程式碼
    'click .deleteButton'(event, templateInstance) {
        Todos.remove({ _id: this._id });
    },
    // 以上
});

Template.hello.helpers({
	todos() {
		return Todos.find({});
	},
});

以上介紹了 Collection 在瀏覽器端的使用,基本上與在伺服器端的用法差不多,最大的差異在於瀏覽器端的 Collection 在網頁重新載入時就會被清除,而在伺服器端的 Collection 則會保存在本地端的 MongoDB,我們是否可以透過伺服器端將資料永久保存,又同時享有瀏覽器端 reactivity 的特性?答案是可以的!明天將會深入介紹 Collection,敬請期待!


上一篇
Day04:Blaze/Spacebar 與模板進階使用+重點整理
下一篇
Day06:MongoDB 與 Collections(二)Publish & Subscribe
系列文
30天快速上手 Meteor - 使用 Universal JavaScript Framework 開發即時聊天大平台8
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言