Meteor 快速指南



Meteor - 概述

根據 Meteor 官方文件:

Meteor 是一個用於開發現代 Web 和移動應用程式的全棧 JavaScript 平臺。Meteor 包含一組關鍵技術,用於構建連線客戶端的反應式應用程式,一個構建工具,以及來自 Node.js 和通用 JavaScript 社群的精選包。

特性

  • Web 和移動端 − Meteor 提供了一個用於開發 Web、Android 和 iOS 應用程式的平臺。

  • 通用應用程式 − 適用於 Web 瀏覽器和移動裝置的同一套程式碼。

  • − 大量易於安裝和使用的包。

  • Meteor Galaxy − 用於 Meteor 應用程式部署的雲服務。

優勢

  • 開發者只需要 JavaScript 即可進行伺服器端和客戶端開發。
  • 編碼非常簡單,易於上手。
  • Meteor 應用預設情況下是即時的。
  • 官方和社群包極大地節省了時間。

侷限性

  • Meteor 不太適合大型和複雜的應用程式。

  • 使用 Meteor 時會發生很多“魔法”,因此開發者可能會發現自己在某些方面受到限制。

Meteor - 環境搭建

在本章中,我們將學習如何在 Windows 作業系統上安裝 Meteor。在開始使用 Meteor 之前,我們需要 NodeJS。如果您尚未安裝,可以檢視下面提供的連結。

先決條件

NodeJS 是 Meteor 開發所需的平臺。如果您還沒有準備好 NodeJS 環境,可以檢視我們的 NodeJS 環境搭建

安裝 Meteor

此頁面 下載官方 Meteor 安裝程式

如果安裝過程中出現任何錯誤,請嘗試以管理員身份執行安裝程式。安裝完成後,系統會要求您建立一個 Meteor 帳戶。

安裝 Meteor 安裝程式後,您可以透過在命令提示符視窗中執行以下程式碼來測試是否一切安裝正確。

C:\Users\username>meteor

輸出如下:

Meteor Installation Test

Meteor - 第一個應用

在本章中,我們將學習如何建立您的第一個 Meteor 應用程式。

步驟 1 - 建立應用程式

要建立應用程式,我們將從命令提示符視窗執行 meteor create 命令。應用程式名稱將為 meteorApp

C:\Users\username\Desktop\Meteor>meteor create meteorApp

步驟 2 - 執行應用程式

我們可以透過鍵入 meteor 命令來執行應用程式。

C:\Users\username\Desktop\meteorApp>meteor

此命令將啟動多個程序,如下圖所示。

Meteor First App Run

步驟 3 - 驗證結果

現在,我們可以開啟 https://:3000/ 地址來檢視我們的第一個 Meteor 應用是什麼樣的。

Meteor First App Output

Meteor - 模板

Meteor 模板使用三個頂級標籤。前兩個是 headbody。這些標籤的功能與常規 HTML 中的相同。第三個標籤是 template。在這裡,我們將 HTML 連線到 JavaScript。

簡單的模板

下面的示例展示了它的工作方式。我們正在建立一個帶有 name = "myParagraph" 屬性的模板。我們的 template 標籤建立在 body 元素的下方,但是我們需要在它渲染到螢幕上之前包含它。我們可以使用 {{> myParagraph}} 語法來實現。在我們的模板中,我們使用了雙大括號 ({{text}})。這是名為 Spacebars 的 Meteor 模板語言。

在我們的 JavaScript 檔案中,我們設定了 Template.myParagraph.helpers({}) 方法,這將是我們與模板的連線。在這個示例中,我們只使用了 text 助手。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <h1>Header</h1>
   {{> myParagraph}}
</body>
 
<template name = "myParagraph">
   <p>{{text}}</p>
</template>

meteorApp.js

if (Meteor.isClient) {
   
   // This code only runs on the client
   Template.myParagraph.helpers({
      text: 'This is paragraph...'
   });
}

儲存更改後,輸出如下:

Meteor Templates Output

塊模板

在下面的示例中,我們使用 {{#each paragraphs}} 迭代 paragraphs 陣列,併為每個值返回模板 name = "paragraph"

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div>
      {{#each paragraphs}}
         {{> paragraph}}
      {{/each}}
   </div>
</body>
 
<template name = "paragraph">
   <p>{{text}}</p>
</template>

我們需要建立 paragraphs 助手。這將是一個包含五個文字值的陣列。

meteorApp.js

if (Meteor.isClient) {
   
   // This code only runs on the client
   Template.body.helpers({
      paragraphs: [
         { text: "This is paragraph 1..." },
         { text: "This is paragraph 2..." },
         { text: "This is paragraph 3..." },
         { text: "This is paragraph 4..." },
         { text: "This is paragraph 5..." }
      ]
   });
}

現在,我們可以看到螢幕上出現了五個段落。

Meteor Templates Output 2

Meteor - 集合

在本章中,我們將學習如何使用 MongoDB 集合。

建立集合

我們可以使用以下程式碼建立一個新的集合:

meteorApp.js

MyCollection = new Mongo.Collection('myCollection');

新增資料

建立集合後,我們可以使用 insert 方法新增資料。

meteorApp.js

MyCollection = new Mongo.Collection('myCollection');

var myData = {
   key1: "value 1...",
   key2: "value 2...",
   key3: "value 3...",
   key4: "value 4...",
   key5: "value 5..."
}

MyCollection.insert(myData);

查詢資料

我們可以使用 find 方法搜尋集合中的資料。

meteorApp.js

MyCollection = new Mongo.Collection('myCollection');

var myData = {
   key1: "value 1...",
   key2: "value 2...",
   key3: "value 3...",
   key4: "value 4...",
   key5: "value 5..."
}

MyCollection.insert(myData);

var findCollection = MyCollection.find().fetch();
console.log(findCollection);

控制檯將顯示我們之前插入的資料。

Meteor Collection Find

我們可以透過新增搜尋引數來獲得相同的結果。

meteorApp.js

MyCollection = new Mongo.Collection('myCollection');

var myData = {
   key1: "value 1...",
   key2: "value 2...",
   key3: "value 3...",
   key4: "value 4...",
   key5: "value 5..."
}

MyCollection.insert(myData);

var findCollection = MyCollection.find({key1: "value 1..."}).fetch();
console.log(findCollection);

更新資料

下一步是更新我們的資料。建立集合並插入新資料後,我們可以使用 update 方法。

meteorApp.js

MyCollection = new Mongo.Collection('myCollection');

var myData = {
   key1: "value 1...",
   key2: "value 2...",
   key3: "value 3...",
   key4: "value 4...",
   key5: "value 5..."
}

MyCollection.insert(myData);

var findCollection = MyCollection.find().fetch();
var myId = findCollection[0]._id;

var updatedData = {
   key1: "updated value 1...",
   key2: "updated value 2...",
   key3: "updated value 3...",
   key4: "updated value 4...",
   key5: "updated value 5..."
}

MyCollection.update(myId, updatedData);

var findUpdatedCollection = MyCollection.find().fetch();
console.log(findUpdatedCollection);

控制檯將顯示我們的集合已更新。

Meteor Collections Update

刪除資料

可以使用 remove 方法從集合中刪除資料。在這個示例中,我們將 id 作為引數來刪除特定資料。

meteorApp.js

MyCollection = new Mongo.Collection('myCollection');

var myData = {
   key1: "value 1...",
   key2: "value 2...",
   key3: "value 3...",
   key4: "value 4...",
   key5: "value 5..."
}

MyCollection.insert(myData);

var findCollection = MyCollection.find().fetch();
var myId = findCollection[0]._id;

MyCollection.remove(myId);

var findDeletedCollection = MyCollection.find().fetch();
console.log(findDeletedCollection);

控制檯將顯示一個空陣列。

Meteor Collections Remove

如果要刪除集合中的所有內容,可以使用相同的方法,但是,我們將使用空物件 {} 代替 id。出於安全原因,我們需要在伺服器端執行此操作。

meteorApp.js

if (Meteor.isServer) {

   MyCollection = new Mongo.Collection('myCollection');

   var myData = {
      key1: "value 1...",
      key2: "value 2...",
      key3: "value 3...",
      key4: "value 4...",
      key5: "value 5..."
   }

   MyCollection.insert(myData);
   MyCollection.remove({});
	
   var findDeletedCollection = MyCollection.find().fetch();
   console.log(findDeletedCollection);
}

我們還可以使用其他引數刪除資料。與前面的示例一樣,Meteor 將強制我們從伺服器端執行此操作。

meteorApp.js

if (Meteor.isServer) {

   MyCollection = new Mongo.Collection('myCollection');

   var myData = {
      key1: "value 1...",
      key2: "value 2...",
      key3: "value 3...",
      key4: "value 4...",
      key5: "value 5..."
   }

   MyCollection.insert(myData);
   MyCollection.remove({key1: "value 1..."});
	
   var findDeletedCollection = MyCollection.find().fetch();
   console.log(findDeletedCollection);
}

可以看出資料已從命令視窗中刪除。

Meteor Collections Remove Server

Meteor - 表單

在本章中,我們將學習如何使用 Meteor 表單。

文字輸入

首先,我們將建立一個帶有文字輸入欄位和提交按鈕的 form 元素。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div>
      {{> myTemplate}}
   </div>
</body>
 
<template name = "myTemplate">
   <form>
      <input type = "text" name = "myForm">
      <input type = "submit" value = "SUBMIT">
   </form>
</template>

在 JavaScript 檔案中,我們將建立 submit 事件。我們需要阻止預設事件行為以阻止瀏覽器重新整理。接下來,我們將獲取輸入欄位的內容並將其賦值給 textValue 變數。

在下面的示例中,我們只將內容記錄到開發人員控制檯中。最後我們需要清除輸入欄位。

meteorApp.js

if (Meteor.isClient) {

   Template.myTemplate.events({

      'submit form': function(event) {
         event.preventDefault();
         var textValue = event.target.myForm.value;
         console.log(textValue);
         event.target.myForm.value = "";
      }
   });
}

當我們在輸入欄位中鍵入“Some text...”並提交時,控制檯將記錄我們輸入的文字。

Meteor Forms Text

單選按鈕

單選按鈕可以使用類似的概念。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div>
      {{> myTemplate}}
   </div>
</body>
 
<template name = "myTemplate">
   <form>
      <input type = "radio" name = "myForm" value = "form-1">FORM 1
      <input type = "radio" name = "myForm" value = "form-2">FORM 2
      <input type = "submit" value = "SUBMIT">
   </form>
</template>

meteorApp.js

if (Meteor.isClient) {

   Template.myTemplate.events({

      'submit form': function(event) {
         event.preventDefault();
         var radioValue = event.target.myForm.value;
         console.log(radioValue);
      }
   });
}

當我們提交第一個按鈕時,控制檯將顯示以下輸出。

Meteor Forms Radio

複選框

下面的示例展示瞭如何使用複選框。您可以看到我們只是重複相同的過程。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div>
      {{> myTemplate}}
   </div>
</body>
 
<template name = "myTemplate">
   <form>
      <input type = "checkbox" name = "myForm" value = "form-1">FORM 1
      <input type = "checkbox" name = "myForm" value = "form-2">FORM 2
      <input type = "submit" value = "SUBMIT">
   </form>
</template>

meteorApp.js

if (Meteor.isClient) {

   Template.myTemplate.events({
   
      'submit form': function(event) {
         event.preventDefault();
         var checkboxValue1 = event.target.myForm[0].checked;
         var checkboxValue2 = event.target.myForm[1].checked;
         console.log(checkboxValue1);
         console.log(checkboxValue2);
      }
   });
}

提交表單後,已選中的輸入將被記錄為 true,而未選中的輸入將被記錄為 false

Meteor Forms Checkbox

下拉選擇

在下面的示例中,我們將學習如何使用 select 元素。我們將使用 change 事件來更新每次選項更改時的資料。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div>
      {{> myTemplate}}
   </div>
</body>
 
<template name = "myTemplate">
   <select>
      <option name = "myOption" value = "option-1">OPTION 1</option>
      <option name = "myOption" value = "option-2">OPTION 2</option>
      <option name = "myOption" value = "option-3">OPTION 3</option>
      <option name = "myOption" value = "option-4">OPTION 4</option>
   </select>
</template>

meteorApp.js

if (Meteor.isClient) {

   Template.myTemplate.events({

      'change select': function(event) {
         event.preventDefault();
         var selectValue = event.target.value;
         console.log(selectValue);
      }
   });
}

如果我們選擇第三個選項,控制檯將記錄選項值。

Meteor Forms Select

Meteor - 事件

在本章中,我們將學習如何使用 標籤、類id 作為事件選擇器。使用事件非常簡單。

讓我們在 HTML 模板中建立三個元素。第一個是 p,第二個是 myClass 類,最後一個是 myId id。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div>
      {{> myTemplate}}
   </div>
</body>
 
<template name = "myTemplate">
   <p>PARAGRAPH...</p>
   <button class = "myClass">CLASS</button>
   <button id = "myId">ID</button>
</template>

在我們的 JavaScript 檔案中,我們為上面建立的三個元素設定了三個事件。您可以看到我們只是在 click 事件後添加了 p、.myClass#myId。這些是我們上面提到的 選擇器

meteorApp.js

if (Meteor.isClient) {

   Template.myTemplate.events({

      'click p': function() {
         console.log("The PARAGRAPH is clicked...");
      },

      'click .myClass': function() {
         console.log("The CLASS is clicked...");
      },

      'click #myId': function() {
         console.log("The ID is clicked...");
      },
   });
}

要測試這一點,我們可以先單擊 PARAGRAPH,然後單擊 CLASS 按鈕,最後單擊 ID 按鈕。我們將得到以下控制檯日誌。

Meteor Events Log

我們可以使用所有其他 JavaScript 事件——click、dbclick、contextmenu、mousedown、mouseup、mouseover、mouseout、mousemove——按照上面的示例。

Meteor - Session

Session 用於在使用者使用應用程式時儲存資料。當用戶離開應用程式時,這些資料將被刪除。

在本章中,我們將學習如何設定 session 物件,儲存一些資料,並返回這些資料。我們將使用基本的 HTML 設定。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div>
      {{> myTemplate}}
   </div>
</body>
 
<template name = "myTemplate">
</template>

現在,我們將使用 Session.set() 方法在本地儲存 myData。設定該方法後,我們可以使用 Session.get() 方法返回它。

meteorApp.js

if (Meteor.isClient) {
  
   var myData = {
      key1: "value1",
      key2: "value2"
   }

   Session.set('mySession', myData);

   var sessionDataToLog = Session.get('mySession');
   console.log(sessionDataToLog);
}

如果我們檢查控制檯,我們將看到已儲存的資料被記錄。

Meteor Session Log

在下一章中,我們將學習如何使用 Session 變數自動更新模板。

Meteor - Tracker

Tracker 是一個小型庫,用於在 Session 變數更改後自動更新模板。在本章中,我們將學習 Tracker 的工作原理。

首先,我們將建立一個 button,用於更新 session。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div>
      {{> myTemplate}}
   </div>
</body>
 
<template name = "myTemplate">
   <button id = "myButton">CLICK ME</button>
</template>

接下來,我們將設定起始 session 值 myData 並建立一個 mySession 物件。Tracker.autorun 方法用於監控 mySession。每當此物件更改時,模板將自動更新。為了測試它,我們將為更新設定一個 click 事件。

meteorApp.js

if (Meteor.isClient) {
  
   var myData = 0
   Session.set('mySession', myData);

   Tracker.autorun(function () {
      var sessionData = Session.get('mySession');
      console.log(sessionData)
   });

   Template.myTemplate.events({

      'click #myButton': function() {
         Session.set('mySession', myData ++);
      }
   });
}

如果我們單擊 CLICK ME 按鈕五次,我們將看到 Tracker 每次 session 更新時都會記錄新值。

Meteor Tracker Log

Meteor - 包

Meteor 提供了數千個社群包,您可以在開發應用程式時使用。

新增包

您可以檢視官方 Meteor 包伺服器 這裡。只需搜尋您需要的包,然後在命令提示符視窗中新增它。例如,如果您想將 http 包新增到您的應用程式,您可以執行以下程式碼:

C:\Users\username\Desktop\meteorApp>meteor add http

刪除包

可以使用類似的原理來刪除包:

C:\Users\username\Desktop\meteorApp>meteor remove http

更新包

您可以執行以下程式碼來更新包:

C:\Users\username\Desktop\meteorApp>meteor update http

檢查當前包

您還可以檢查當前應用程式正在使用哪些包。

C:\Users\username\Desktop\meteorApp>meteor list

包維護

如果包的名稱中包含 :,則表示它是社群包,而沒有字首的包由 Meteor 開發組維護。

新增 Meteor 開發組包

C:\Users\username\Desktop\meteorApp>meteor add http

新增社群包

C:\Users\username\Desktop\meteorApp>meteor add cfs:http-methods

Meteor - 核心 API

如果您想限制程式碼僅在伺服器端或客戶端執行,可以使用以下程式碼:

meteorApp.js

if (Meteor.isClient) {
   // Code running on client...
}

if (Meteor.isServer) {
   // Code running on server...
}

您可以限制程式碼僅在應用程式使用 Cordova 打包時執行。

if (Meteor.isCordova) {
   // Code running on Cordova...
}

有些外掛需要等待伺服器和 DOM 準備好。您可以使用以下程式碼等待一切開始。

Meteor.startup(function () {
   // Code running after platform is ready...
});

下表列出了一些其他核心 API 方法。

序號 方法及詳情
1

Meteor.wrapAsync(function)

用於包裝非同步程式碼並將其轉換為同步程式碼。

2

Meteor.absoluteUrl([path], [options])

用於生成指向應用程式的絕對URL。

3

Meteor.settings

用於設定部署配置。

4

Meteor.publish(name, function)

用於將記錄釋出到客戶端。

Meteor - 檢查

check 方法用於檢查引數或型別是否與模式匹配。

安裝 Check 包

開啟命令提示符視窗並安裝包。

C:\Users\username\Desktop\meteorApp>meteor add check

使用 Check

在下面的示例中,我們想檢查myValue是否為字串。由於它是真值,應用程式將繼續執行而不會出現任何錯誤。

meteorApp.js

var myValue = 'My Value...';
check(myValue, String);

在這個示例中,myValue不是字串而是數字,因此控制檯將記錄錯誤。

meteorApp.js

var myValue = 1;
check(myValue, String);
Meteor Check Log Error

Match Test

Match.test類似於check,區別在於測試失敗時,不會出現控制檯錯誤,而是會得到一個而不會中斷伺服器。以下示例演示如何測試具有多個鍵的物件。

meteorApp.js

var myObject = {
   key1 : "Value 1...",
   key2 : "Value 2..."
}

var myTest = Match.test(myObject, {
   key1: String,
   key2: String
});

if ( myTest ) {
   console.log("Test is TRUE...");
} else {
   console.log("Test is FALSE...");
}

由於兩個鍵都是字串,因此測試結果為true。控制檯將記錄第一個選項。

Meteor Match Test True

如果我們將key2更改為數字,則測試將失敗,控制檯將記錄第二個選項。

meteorApp.js

var myObject = {
   key1 : "Value 1...",
   key2 : 1
}

var myValue = 1;

var myTest = Match.test(myObject, {
   key1: String,
   key2: String
});

if ( myTest ) {
   console.log("Test is TRUE...");
} else {
   console.log("Test is FALSE...");
}
Meteor Match Test False

Meteor - Blaze

Blaze 是一個用於構建即時響應式模板的 Meteor 包。

渲染方法

此方法用於將模板渲染到 DOM。首先,我們將建立將要渲染的myNewTemplate。我們還將新增myContainer,它將用作父元素,以便render方法知道在哪裡渲染我們的模板。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div id = "myContainer">
   </div>
</body>

<template name = "myNewTemplate">
   <p>Text from my new template...</p>
</template>

接下來,我們將建立一個渲染函式,它將接受兩個引數。第一個是要渲染的模板,第二個是我們上面提到的父元素。

meteorApp.js

Meteor.startup(function () {

   if(Meteor.isClient) {
      var myNewTemplate = Template.myNewTemplate;
      var myContainer = document.getElementById('myContainer');
      Blaze.render(myNewTemplate, myContainer);
   }
});
Meteor Blaze Render

使用資料進行渲染

如果需要以響應方式傳遞一些資料,可以使用renderWithData方法。HTML 將與上一個示例完全相同。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div id = "myContainer">
   </div>
</body>

<template name = "myNewTemplate">
   <p>Text from my new template...</p>
</template>

我們可以在Meteor.renderWithData方法中將資料作為第二個引數新增。其他兩個引數與上一個示例相同。在這個示例中,我們的資料是一個將記錄一些文字的函式。

meteorApp.js

Meteor.startup(function () {

   if(Meteor.isClient) {
      var myNewTemplate = Template.myNewTemplate;
		
      var myData = function() {
         console.log('Log from the data object...')
      }

      var myContainer = document.getElementById('myContainer');
      Blaze.renderWithData(myNewTemplate, myData, myContainer);
   }
});
Meteor Blaze Render With Data

移除方法

我們可以新增remove方法。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div id = "myContainer">
   </div>
</body>

<template name = "myNewTemplate">
   <p>Text from my new template...</p>
</template>

在這個示例中,我們正在渲染一個將在三秒鐘後移除的模板。請注意我們用來移除模板的Blaze.Remove方法。

meteorApp.js

Meteor.startup(function () {

   if(Meteor.isClient) {
      var myNewTemplate = Template.myNewTemplate;
      var myContainer = document.getElementById('myContainer');
      var myRenderedTemplate = Blaze.render(myNewTemplate, myContainer);

      Meteor.setTimeout(function() {
         Blaze.remove(myRenderedTemplate);
      }, 3000);
   }
});

下表顯示了可使用的其他方法。

序號 方法及詳情
1

Blaze.getData([elementOrView])

用於從渲染元素中檢索資料。

2

Blaze.toHTML(templateOrView)

用於將模板或檢視渲染為字串。

3

Blaze.toHTMLWithData(templateOrView, data)

用於將模板或檢視渲染為帶有附加資料的字串。

4

new Blaze.View([name], renderFunction)

用於建立 DOM 的一個新的 Blaze 響應式部分。

5

Blaze.currentView

用於獲取當前檢視。

6

Blaze.getView([element])

用於獲取當前檢視。

7

Blaze.With(data, contentFunc)

用於構造一個使用上下文渲染某些內容的檢視。

8

Blaze.If(conditionFunc, contentFunc, [elseFunc])

用於構造一個渲染某些條件內容的檢視。

9

Blaze.Unless(conditionFunc, contentFunc, [elseFunc])

用於構造一個渲染某些條件內容的檢視(Blaze.if 的反向操作)。

10

Blaze.Each(argFunc, contentFunc, [elseFunc])

用於構造一個為每個專案渲染contentFunc的檢視。

11

new Blaze.Template([viewName], renderFunction)

用於使用名稱和內容構造一個新的 Blaze 檢視。

12

Blaze.isTemplate(value)

如果值為模板物件,則返回 true。

Meteor - 定時器

Meteor 提供了自己的setTimeoutsetInterval方法。這些方法用於確保所有全域性變數具有正確的的值。它們的工作方式與普通的 JavaScript setTimoutsetInterval相同。

超時

這是一個Meteor.setTimeout示例。

Meteor.setTimeout(function() {
   console.log("Timeout called after three seconds...");
}, 3000);

我們可以在控制檯中看到,一旦應用程式啟動,超時函式就會被呼叫。

Meteor Timeout

間隔

以下示例演示如何設定和清除間隔。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   <div>
      {{> myTemplate}}
   </div>
</body>
 
<template name = "myTemplate">
   <button>CLEAR</button>
</template>

我們將設定初始counter變數,該變數將在每次間隔呼叫後更新。

meteorApp.js

if (Meteor.isClient) {

   var counter = 0;

   var myInterval = Meteor.setInterval(function() {
      counter ++
      console.log("Interval called " + counter + " times...");
   }, 3000);

   Template.myTemplate.events({

      'click button': function() {
         Meteor.clearInterval(myInterval);
         console.log('Interval cleared...')
      }
   });
}

控制檯將每三秒鐘記錄一次更新後的counter變數。我們可以透過單擊CLEAR按鈕來停止此操作。這將呼叫clearInterval方法。

Meteor Interval

Meteor - EJSON

EJSON 是 JSON 語法的擴充套件,支援DateBinary型別。

安裝 EJSON

要安裝 EJSON 包,我們需要從命令提示符視窗中新增它。

C:\Users\username\Desktop\meteorApp>meteor add ejson

日期示例

我們可以使用parse方法反序列化date

if (Meteor.isClient) {
   var myEjsonDate = '{"$date": 1455029631493}';
   var myDate = EJSON.parse(myEjsonDate);
   console.log(myDate);
}

控制檯將記錄正確的日期值。

Meteor EJSON Date

二進位制示例

同樣的方法可以應用於二進位制型別。

if (Meteor.isClient) {
   var myEjsonBinary = '{"$binary": "c3VyZS4="}';
   var myBinary = EJSON.parse(myEjsonBinary);
   console.log(myBinary);
}

您可以看到控制檯正在記錄新的反序列化值。

Meteor EJSON Binary

序列化

我們可以使用stringify方法序列化物件。這是上面示例的反向過程。

if (Meteor.isClient) {

   var myObject = {
      myDate : new Date(),
      myBinary : new Uint8Array([115, 117, 114, 101, 46])
   }

   var myEjosnData = EJSON.stringify(myObject);
   console.log(myEjosnData);
}

我們可以在控制檯中看到我們的新值。

Meteor EJSON Stringify

序號 方法及詳情
1

EJSON.parse(string)

用於將字串解析為 EJSON 值。

2

EJSON.stringify(value)

用於將值序列化為字串。

3

EJSON.fromJSONValue(value)

用於從 JSON 反序列化 EJSON 值。

4

EJSON.toJSONValue(value)

用於將 EJSON 值序列化為 JSON。

5

EJSON.equals(value1, value2)

用於比較兩個值是否相等。

6

EJSON.clone(value)

用於返回值的深複製。

7

EJSON.newBinary

用於賦值 EJSON 可以序列化的二進位制資料。

8

EJSON.isBinary(x)

用於檢查值是否為二進位制資料。

9

EJSON.addType(name, factory)

用於建立自定義 EJSON 型別。

10

customType.typeName()

用於返回自定義型別的名稱。

11

customType.toJSONValue()

用於序列化自定義型別。

12

customType.clone()

用於返回自定義型別的深複製。

13

customType.equals(otherValue)

用於比較自定義型別值和其他值。

Meteor - HTTP

此包提供帶有get、post、putdelete方法的 HTTP 請求 API。

安裝包

我們將在命令提示符視窗中執行以下程式碼來安裝此包。

C:\Users\username\Desktop\meteorApp>meteor add http

CALL 方法

這是一個通用方法,可以使用GETPOSTPUTDELETE引數。以下示例演示如何使用GET引數。本章中的示例將使用來自此網站的偽造 REST API。

您可以看到此方法使用了四個引數。我們已經提到了第一個引數GET。第二個是 API URL。第三個引數是一個空物件,我們可以在其中設定一些可選引數。最後的方法是一個非同步回撥,我們可以在其中處理錯誤並使用響應。

HTTP.call( 'GET', 'http://jsonplaceholder.typicode.com/posts/1', {},
   function( error, response ) {

   if (error) {
      console.log(error);
   } else {
      console.log(response);
   }
});

GET 方法

可以使用GET代替CALL方法傳送相同的請求。您可以看到第一個引數現在是 API URL。

HTTP.get('http://jsonplaceholder.typicode.com/posts/1', {}, function( error, response ) {

   if ( error ) {
      console.log( error );
   } else {
      console.log( response );
   }
});

前面兩個示例將記錄相同的輸出。

Meteor HTTP Call

POST 方法

在此方法中,我們將需要傳送到伺服器的資料 (postData) 作為第二個引數。其他所有內容與我們的GET請求相同。

var postData = {

   data: {
      "name1": "Value1",
      "name2": "Value2",
   }
}

HTTP.post( 'http://jsonplaceholder.typicode.com/posts', postData, 
   function( error, response ) {

   if ( error ) {
      console.log( error );
   } else {
      console.log( response);
   }
});

控制檯將記錄我們的postData物件。

Meteor HTTP Post

PUT 方法

我們可以使用PUT方法更新我們的資料。概念與我們上一個示例相同。

var updateData = {

   data: {
      "updatedName1": "updatedValue1",
      "UpdatedName2": "updatedValue2",
   }
}

HTTP.put( 'http://jsonplaceholder.typicode.com/posts/1', updateData, 
   function( error, response ) {
	
   if ( error ) {
      console.log( error );
   } else {
      console.log( response );
   }
});

現在,我們可以在控制檯中看到我們更新後的物件。

Meteor HTTP Put

DEL 方法

我們可以使用DEL方法向伺服器傳送刪除請求。我們將刪除data物件中的所有內容。

var deleteData = {
   data: {}
}

HTTP.del( 'http://jsonplaceholder.typicode.com/posts/1', deleteData, 
   function( error, response ) {
	
   if ( error ) {
      console.log( error );
   } else {
      console.log( response );
   }
});

控制檯將顯示刪除過程成功。

Meteor HTTP Del

Meteor - 郵件

當您需要從 Meteor 應用程式傳送電子郵件時,可以使用此包。

步驟 1 - 新增包

開啟命令提示符視窗並執行以下命令:

C:\Users\username\Desktop\meteorApp>meteor add email

步驟 2 - Mailgun 帳戶

我們需要在這裡建立一個帳戶這裡。這是 Meteor 應用程式的預設電子郵件提供商。

登入後,開啟Domains選項卡,然後單擊Domain Name下方的sandbox URL。它將開啟一個新頁面,我們可以在其中找到Default SMTP LoginDefault Password。建立MAIL_URL環境變數需要這兩個值。

傳送電子郵件

要建立一個有效的MAIL_URL,只需將您的 Mailgun 憑據插入YOUR_DEFAULT_SMTP_LOGINYOUR_DEFAULT_PASSWORD的位置。

if (Meteor.isServer) {

   Meteor.startup( function() {
      process.env.MAIL_URL = 
         "smtp://YOUR_DEFAULT_SMTP_LOGIN:YOUR_DEFAULT_PASSWORD@smtp.mailgun.org:587";

      Email.send({
         to: "toemailadress@email.com",
         from: "fromemailadress@email.com",
         subject: "Meteor Email",
         text: "The email content..."
      });
   });
}

執行應用程式時,電子郵件將傳送到您的地址。

Meteor Email Received

Meteor - 資源

靜態伺服器資源位於應用程式內的private子資料夾中。在以下示例中,我們將學習如何使用簡單 JSON 檔案中的資料。

步驟 1 - 建立檔案和資料夾

讓我們建立一個private資料夾和該資料夾內的my-json.json檔案。我們將使用命令提示符視窗中的以下命令執行此操作,但是您也可以手動建立它。

C:\Users\username\Desktop\meteorApp>mkdir private

C:\Users\username\Desktop\meteorApp\private>touch my-json.json

步驟 2 - 獲取文字

為了能夠讀取檔案中的資料,我們將使用Asssets.getText方法。請注意,這隻能在伺服器端完成。由於我們使用的是 JSON,因此需要對其進行解析。

if (Meteor.isServer) {
   var myFile = JSON.parse(Assets.getText('my-json.json'));
   console.log(myFile.data.text)
}

命令提示符視窗中的輸出如下。

Meteor Assets Get Text

步驟 3 - 建立 EJSON 檔案

我們將在private資料夾內建立此檔案。此檔案將包含二進位制資料"myBinary": {"$binary": "c3VyZS4="}

C:\Users\username\Desktop\meteorApp\private>touch my-ejson.ejson

步驟 4 - 獲取二進位制資料

要讀取 EJSON 檔案,我們可以使用Assets.getBinary方法。

if (Meteor.isServer) {
   var myFile = Assets.getBinary('my-ejson.ejson');
   console.log(EJSON.stringify(myFile));
}

命令提示符將記錄 EJSON 值。

Meteor Assets Get Binary

Meteor - 安全

在本章中,我們將學習如何保護我們的應用程式,以及在開發應用程式時應考慮的事項。

Autopublish 和 Insecure

Autopublish是一個自動將資料庫中的所有資料釋出到客戶端的包。這是一個便利功能,在生產環境中應將其停用。可以從命令提示符停用它。

C:\Users\username\Desktop\meteorApp>meteor remove autopublish

您可以使用Meteor.publish()Meteor.subscribe()方法將一些資料釋出到客戶端,我們將在“釋出和訂閱”一章中介紹這些方法。

Insecure是一個允許在開發者控制檯中編寫 MongoDB 命令的包,這樣應用程式的每個使用者都能夠訪問資料庫。可以透過在命令提示符中執行以下命令來刪除該包。

C:\Users\username\Desktop\meteorApp>meteor remove insecure

良好的做法是在您開始開發應用程式後立即刪除這兩個包,這樣您以後就不必更改和更新程式碼了。

使用伺服器端方法

您應該始終在伺服器上建立方法。您可以使用伺服器上的Meteor.methods()和客戶端上的Meteor.call()來做到這一點。我們將在方法一章中詳細瞭解這一點。

其他安全措施

如果您想為您的應用程式新增額外的安全層,您應該考慮使用其他一些 Meteor 包,例如:

  • 瀏覽器策略 (Browser Policy) 可用於控制應載入到您的應用程式的外部資源。

  • Check 包可用於檢查使用者輸入型別,然後再進行處理。

  • 審計引數檢查 (Audit Arguments Check) 是一個包,它將確保在處理之前正確檢查所有引數。如果您錯過了某些引數,此包將通知您。

  • Mylar 包可以新增一些額外的安全層。如果您需要那種保護,可以檢視它們。

Meteor - 排序

我們可以在從資料庫獲取資料後對其進行排序。在下面的示例中,我們將建立一個 **Users** 集合。我們將使用 **sort** 引數 (**{sort: {name: 1}}**) 來按名稱對集合資料進行排序。數字 **1** 用於設定升序。如果我們想使用降序,我們將使用 **-1** 代替。

Users = new Mongo.Collection('users');

Users.insert({
   name: 'James',
   email: 'eee@example.com',
   joined: new Date(2016, 2, 23)
});

Users.insert({
   name: 'John',
   email: 'iii@example.com',
   joined: new Date(2016, 2, 19)
});

Users.insert({
   name: 'Jennifer',
   email: 'aaa@example.com',
   joined: new Date(2016, 6, 24)
});

var sortByName = Users.find({}, {sort: {name: 1}}).fetch();

var sortByEmail = Users.find({}, {sort: {email: 1}}).fetch();

var sortByJoined = Users.find({}, {sort: {joined: 1}}).fetch();

console.log(sortByName);
console.log(sortByEmail);
console.log(sortByJoined);
Meteor Sorting Name

我們可以用同樣的方法按電子郵件對資料進行排序。

Users = new Mongo.Collection('users');

Users.insert({
   name: 'James',
   email: 'eee@example.com',
   joined: new Date(2016, 2, 23)
});

Users.insert({
   name: 'John',
   email: 'iii@example.com',
   joined: new Date(2016, 2, 19)
});

Users.insert({
   name: 'Jennifer',
   email: 'aaa@example.com',
   joined: new Date(2016, 6, 24)
});

var sortByEmail = Users.find({}, {sort: {email: 1}}).fetch();

console.log(sortByEmail);
Meteor Sorting Email

最後,我們可以按加入日期對其進行排序。

Users = new Mongo.Collection('users');

Users.insert({
   name: 'James',
   email: 'eee@example.com',
   joined: new Date(2016, 2, 23)
});

Users.insert({
   name: 'John',
   email: 'iii@example.com',
   joined: new Date(2016, 2, 19)
});

Users.insert({
   name: 'Jennifer',
   email: 'aaa@example.com',
   joined: new Date(2016, 6, 24)
});

var sortByJoined = Users.find({}, {sort: {joined: 1}}).fetch();

console.log(sortByJoined);
Meteor Sorting Joined

Meteor - 賬戶

此包允許完整的使用者身份驗證功能。您可以透過在命令提示符視窗中執行以下程式碼來新增它。

C:\Users\username\Desktop\meteorApp>meteor add accounts-password

身份驗證示例

此示例將顯示基本身份驗證。我們將建立 **register**、**login** 和 **home** 模板。如果存在 **currentUser**(如果使用者已成功註冊或登入),則將顯示 **home** 模板。如果沒有 **currentUser**,則 **register** 和 **login** 模板將可見。

meteorApp.html

<head>
   <title>meteorApp</title>
</head>
 
<body>
   {{#if currentUser}}
      {{> home}}
      {{else}}
      {{> register}}
      {{> login}}
   {{/if}}
</body>

<template name = "register">
   <h2>REGISTER:</h2>
   <form>
      <input type = "email" name = "registerEmail"><br>
      <input type = "password" name = "registerPassword"><br>
      <input type = "submit" value = "Register"><br>
   </form>
</template>

<template name = "login">
   <h2>LOGIN:</h2>
   <form>
      <input type = "email" name = "loginEmail"><br>
      <input type = "password" name="loginPassword"><br>
      <input type = "submit" value = "Login"><br>
   </form>
</template>

<template name = "home">
   <p>You're logged in.</p>
   <button class = "logout">Logout</button>
</template>

首先,我們需要建立一個 **register** 事件。此函式將讀取註冊輸入,建立一個新使用者,並將其儲存到資料庫中。

第二個事件是 **login**。這次函式將讀取 **login** 模板中的輸入,如果電子郵件和密碼有效,則登入使用者;如果無效,則返回錯誤。

最後,**logout** 事件將在單擊按鈕後用於登出使用者。

meteorApp.js

if (Meteor.isClient) {

   Template.register.events({
      'submit form': function(event) {
         event.preventDefault();

         var registerData = {
            email: event.target.registerEmail.value,
            password: event.target.registerPassword.value
         }

         Accounts.createUser(registerData, function(error) {
         
            if (Meteor.user()) {
               console.log(Meteor.userId());
            } else {
               console.log("ERROR: " + error.reason);
            }
         });
      }
   });

   Template.login.events({
   
      'submit form': function(event) {
         event.preventDefault();
         var myEmail = event.target.loginEmail.value;
         var myPassword = event.target.loginPassword.value;
			
         Meteor.loginWithPassword(myEmail, myPassword, function(error) {

            if (Meteor.user()) {
               console.log(Meteor.userId());
            } else {
               console.log("ERROR: " + error.reason);
            }
         });
      }
   });

   Template.home.events({

      'click .logout': function(event) {
         event.preventDefault();
			
         Meteor.logout(function(error) {

            if(error) {
               console.log("ERROR: " + error.reason);
            }
         });
      }
   });
}

應用程式啟動後,我們將看到以下頁面。

Meteor Accounts Start

在 **register** 表單中輸入電子郵件和密碼後,我們可以註冊和登入新使用者。我們將看到控制檯記錄使用者的 **id** 並呈現 **home** 模板。

Meteor Accounts Register

**login** 事件將檢查資料庫並登入使用者(如果電子郵件和密碼正確)。如果不是,控制檯將記錄錯誤。

Meteor Accounts Login Error

如果使用者單擊 **LOGOUT** 按鈕,應用程式將登出使用者並顯示 **register** 和 **login** 模板。

Meteor - 方法

Meteor 方法是在伺服器端編寫的函式,但可以從客戶端呼叫。

在伺服器端,我們將建立兩個簡單的函式。第一個函式將向我們的引數新增 5,而第二個函式將新增 **10**。

使用方法

meteorApp.js

	
if(Meteor.isServer) {

   Meteor.methods({

      method1: function (arg) {
         var result = arg + 5;
         return result;
      },

      method2: function (arg) {
         var result = arg + 10;
         return result;
      }
   });
}

if(Meteor.isClient) {
   var aaa = 'aaa'
   Meteor.call('method1', aaa, function (error, result) {
	
      if (error) {
         console.log(error);
         else {
            console.log('Method 1 result is: ' + result);
         }
      }
   );

   Meteor.call('method2', 5, function (error, result) {

      if (error) {
         console.log(error);
      } else {
         console.log('Method 2 result is: ' + result);
      }
   });
}

啟動應用程式後,我們將在控制檯中看到計算出的值。

Meteor Methods Log

處理錯誤

要處理錯誤,您可以使用 **Meteor.Error** 方法。以下示例顯示瞭如何處理未登入使用者的錯誤。

if(Meteor.isServer) {

   Meteor.methods({

      method1: function (param) {

         if (! this.userId) {
            throw new Meteor.Error("logged-out",
               "The user must be logged in to post a comment.");
         }
         return result;
      }
   });
}

if(Meteor.isClient) {  Meteor.call('method1', 1, function (error, result) {

   if (error && error.error === "logged-out") {
      console.log("errorMessage:", "Please log in to post a comment.");
   } else {
      console.log('Method 1 result is: ' + result);
   }});

}

控制檯將顯示我們自定義的錯誤訊息。

Meteor Methods Error

Meteor - Package.js

在本章中,我們將學習如何建立我們自己的 Meteor 包。

建立包

讓我們在桌面上新增一個新資料夾,將在其中建立包。我們將使用命令提示符視窗。

C:\Users\username\Desktop\meteorApp> mkdir packages

現在,我們可以在上面建立的資料夾中建立包。從命令提示符執行以下命令。**使用者名稱** 是 Meteor 開發人員使用者名稱,**包名稱** 是包的名稱。

C:\Users\username\Desktop\meteorApp\packages>meteor create --package username:package-name

新增包

為了能夠將本地包新增到我們的應用程式,我們需要設定 **環境變數**,它將告訴 Meteor 從本地資料夾載入包。右鍵單擊計算機圖示,然後選擇 **屬性/高階系統設定/環境變數/新建**。

**變數名** 應為 **PACKAGE_DIRS**。**變數值** 應為我們建立的資料夾的路徑。在本例中,為 **C:\Users\username\Desktop\meteorApp\packages**。

新增新的環境變數後,不要忘記重新啟動 **命令提示符**。

現在,我們可以透過執行以下程式碼將包新增到我們的應用程式:

C:\Users\username\Desktop\meteorApp>meteor add username:package-name

包檔案

在我們建立的包中將找到以下四個檔案。

  • package-name-test.js
  • package-name.js
  • package.js
  • README.md

測試包 (package-name-test.js)

Meteor 提供了 **tinytest** 包用於測試。讓我們首先使用命令提示符視窗中的以下命令安裝它。

C:\Users\username\Desktop\meteorApp>meteor add tinytest

如果我們開啟 **package-name-test.js**,我們將看到預設的測試示例。我們將使用此示例來測試應用程式。注意:在開發 Meteor 包時,最好編寫自己的測試。

要測試包,讓我們在命令提示符中執行此程式碼。

C:\Users\username\Desktop>meteor test-packages packages/package-name

我們將得到以下結果。

Meteor Package Test

package.js 檔案

這是我們可以編寫程式碼的檔案。讓我們為我們的包建立一些簡單的功能。我們的包將在控制檯中記錄一些文字。

packages/package.js

myPackageFunction = function() {
   console.log('This is simple package...');
}

package-name.js 檔案

這是我們可以設定一些包配置的檔案。我們稍後會回到它,但現在我們需要匯出 **myPackageFunction** 以便我們可以在我們的應用程式中使用它。我們需要在 **Package.onUse** 函式內新增它。該檔案看起來像這樣。

packages/package-name.js

Package.describe({
   name: 'username:package-name',
   version: '0.0.1',
   
   // Brief, one-line summary of the package.
   summary: '',
   
   // URL to the Git repository containing the source code for this package.
   git: '',
   
   // By default, Meteor will default to using README.md for documentation.
   
   // To avoid submitting documentation, set this field to null.
   documentation: 'README.md'
});

Package.onUse(function(api) {
   api.versionsFrom('1.2.1');
   api.use('ecmascript');
   api.addFiles('mypackage.js');
   api.export('myPackageFunction'); // We are exporting the function we created above...
});

Package.onTest(function(api) {
   api.use('ecmascript');
   api.use('tinytest');
   api.use('username:package-name');
   api.addFiles('package-name-tests.js');
});

使用包

現在我們終於可以從我們的 **meteorApp.js** 檔案中呼叫 **myPackageFunction()** 了。

packages/package.js

if(Meteor.isClient) {
   myPackageFunction();
}

控制檯將記錄來自我們包的文字。

Meteor Package Log

為了更好地理解如何配置 **package.js** 檔案,我們將使用 Meteor 官方文件中的示例。

這是一個示例檔案……

/* Information about this package */
Package.describe({
   
   // Short two-sentence summary.
   summary: "What this does",

   // Version number.
   version: "1.0.0",

   // Optional.  Default is package directory name.
   name: "username:package-name",

   // Optional github URL to your source repository.
   git: "https://github.com/something/something.git",
});

/* This defines your actual package */
Package.onUse(function (api) {

   // If no version is specified for an 'api.use' dependency, use the
   // one defined in Meteor 0.9.0.
   api.versionsFrom('0.9.0');

   // Use Underscore package, but only on the server.
   // Version not specified, so it will be as of Meteor 0.9.0.
   api.use('underscore', 'server');

   // Use iron:router package, version 1.0.0 or newer.
   api.use('iron:router@1.0.0');

   // Give users of this package access to the Templating package.
   api.imply('templating')

   // Export the object 'Email' to packages or apps that use this package.
   api.export('Email', 'server');

   // Specify the source code for the package.
   api.addFiles('email.js', 'server');
});

/* This defines the tests for the package */
Package.onTest(function (api) {

   // Sets up a dependency on this package
   api.use('username:package-name');

   // Allows you to use the 'tinytest' framework
   api.use('tinytest@1.0.0');

   // Specify the source code for the package tests
   api.addFiles('email_tests.js', 'server');
});

/* This lets you use npm packages in your package*/
Npm.depends({
   simplesmtp: "0.3.10",
   "stream-buffers": "0.2.5"
});

Meteor - 釋出和訂閱

正如在集合章節中已經討論的那樣,我們所有的資料都可以在客戶端上使用。這是一個安全問題,可以使用釋出和訂閱方法來處理。

刪除 Autopublish

在這個例子中,我們將使用 **PlayersCollection** 集合以及以下資料。我們之前準備了這個集合,以便能夠專注於本章本身。如果您不確定如何在 Meteor 應用程式中建立 MongoDB 集合,請檢視我們的 集合 章節。

Meteor Publish and Subscribe Database Data

為了保護我們的資料,我們需要刪除允許我們在客戶端使用資料的 **autopublish** 包。

C:\Users\username\Desktop\meteorApp>meteor remove autopublish

此步驟之後,我們將無法從客戶端獲取資料庫資料。我們只能在命令提示符視窗的伺服器端看到它。檢視以下程式碼:

meteorApp.js

var PlayersCollection = new Mongo.Collection('playersCollection');
var myLog = PlayersCollection.find().fetch();
console.log(myLog);

**命令提示符** 視窗將顯示包含四個物件的整個集合,而 **開發者控制檯** 將顯示一個空陣列。現在我們的應用程式更安全了。

Meteor Publish and Subscribe Autopublish Removed

使用釋出和訂閱

假設我們想允許客戶端使用我們的資料。為此,我們需要在伺服器上建立 **Meteor.publish()** 方法。此方法將資料傳送到客戶端。

為了能夠在客戶端接收和使用該資料,我們將建立 **Meteor.subscribe()** 方法。在示例的末尾,我們正在搜尋資料庫。此程式碼在客戶端和伺服器端都執行。

var PlayersCollection = new Mongo.Collection('playersCollection');

if(Meteor.isServer) {

   Meteor.publish('allowedData', function() {
      return PlayersCollection.find();
   })
}

if (Meteor.isClient) {
   Meteor.subscribe('allowedData');
};

Meteor.setTimeout(function() {
   var myLog = PlayersCollection.find().fetch();
   console.log(myLog);
}, 1000);

我們可以看到我們的資料已記錄在 **開發者控制檯** 和 **命令提示符** 視窗中。

Meteor Publish and Subscribe Allowed All

過濾客戶端資料

我們還可以釋出部分資料。在這個例子中,我們正在釋出名稱為 **"John"** 的資料。

var PlayersCollection = new Mongo.Collection('playersCollection');

if(Meteor.isServer) {

   Meteor.publish('allowedData', function() {
      return PlayersCollection.find({name: "John"});
   })
}

if (Meteor.isClient) {
   Meteor.subscribe('allowedData');
};

Meteor.setTimeout(function() {
   myLog = PlayersCollection.find().fetch();
   console.log(myLog);
}, 1000);

執行此程式碼後,**命令提示符** 將記錄所有資料,而客戶端 **控制檯** 將只記錄兩個名稱為 **John** 的物件。

Meteor Publish and Subscribe Allowed All

Meteor - 結構

Meteor 提供了一些特殊的資料夾,可以幫助開發人員構建他們的應用程式。

client

如果您建立一個 **client** 資料夾,則此資料夾中的所有內容都將在客戶端執行。這是您可以放置 **HTML、CSS** 和客戶端 **JavaScript** 的資料夾。您應該在此資料夾中放置 **Meteor.subscribe** 函式、**模板、助手** 和 **事件**。請注意,您不需要在放在 **client** 資料夾中的檔案中執行 **Meteor.isClient** 函式。

server

此資料夾中的檔案將僅在 **伺服器端** 執行。這是應該儲存 **方法、Meteor.Publish()** 函式和其他敏感資料的地方。所有身份驗證資料都應儲存在此處。您不需要對此資料夾內的檔案使用 **Meteor.isServer()**。

public

這是您應該放置影像、網站圖示以及所有其他提供給客戶端的資料的地方。

private

只能從伺服器訪問此資料夾中的檔案。它們將對客戶端隱藏。您可以將僅伺服器使用的 **JSON** 或 **EJSON** 檔案放在此資料夾中。

client/compatibility

一些 JavaScript 庫將變數匯出為全域性變數。將需要在不包含在新變數作用域中執行的檔案用於此資料夾。

其餘部分

其餘資料夾可以按照您想要的方式進行組織。放在上述資料夾之外的程式碼將在 **客戶端** 和 **伺服器端** 執行。這是一個您可以定義模型的好地方。

載入順序

瞭解檔案的載入順序總是好的。以下列表取自 Meteor 官方文件。

  • HTML 模板檔案始終在其他所有內容之前載入

  • 以 **main.** 開頭的檔案最後載入

  • 任何 **lib/** 目錄中的檔案接下來載入

  • 路徑較深的檔案接下來載入

  • 然後按整個路徑的字母順序載入檔案

Meteor - 部署

Meteor 的一大優點是部署應用程式非常容易。應用程式完成後,有一種簡單的方法可以與世界分享。您只需在命令提示符視窗中執行以下程式碼即可。

C:\Users\username\Desktop\meteorApp>meteor deploy my-first-app-ever.meteor.com

系統會要求您輸入 Meteor 開發者帳戶的使用者名稱密碼

現在,您可以透過以下連結訪問瀏覽器中的應用程式,連結名稱為您的應用程式名稱。

http://my-first-app-ever.meteor.com/
Meteor Deploy

Meteor - 移動端執行

在本章中,我們將學習如何在 Android 裝置上執行應用程式。Meteor 最近才為 Windows 作業系統添加了此功能,因此我們需要將我們的 Meteor 應用程式更新到 1.3 Beta 版本。

注意 - 在撰寫本教程時,Meteor 的 1.3 版本處於 Beta 階段。正式版釋出後,我們會更新此內容。

由於我們想使用最新的 Meteor 版本,我們可以透過在命令提示符視窗中執行以下程式碼來更新它。

C:\Users\username\Desktop\meteorApp>meteor update --release 1.3-beta.11

步驟 1 - 安裝 Android SDK

使用下表中的連結安裝 Android SDK。

序號 軟體及說明
1

Java 開發工具包和 Android SDK

您需要 Android SDK 才能在移動環境中執行 Meteor 應用程式。如果您尚未安裝它,您可以檢視我們的 Android 環境設定 教程。

步驟 2 - 新增 Android 平臺

現在,我們需要向專案中新增一個 Android 平臺。

C:\Users\username\Desktop\meteorApp>meteor add-platform android

步驟 3 - 在 Android 模擬器上執行應用程式

要在 Android 模擬器上執行應用程式,我們將在行尾使用–verbose命令,以便能夠識別啟動過程中的潛在錯誤。

C:\Users\username\Desktop\meteorApp>meteor run android --verbose

Meteor Mobile

在 Android 裝置上執行應用程式

由於 Android 模擬器速度較慢,直接在您的裝置上執行應用程式始終是更好的選擇。您可以透過將裝置連線到計算機,啟用開發者模式和 USB 除錯來實現。

此過程因特定裝置而異。您需要在設定/關於中找到內部版本號,然後點選七次。您將收到一條通知,告知您是開發者,並且開發者選項將被解鎖。

再次搜尋您的設定並啟用USB 除錯

您可以在命令提示符中使用以下命令在移動裝置上執行 Meteor 應用程式。

C:\Users\username\Desktop\meteorApp>meteor run android-device

Meteor - 待辦事項應用

在本章中,我們將學習如何建立一個簡單的待辦事項應用程式。

步驟 1 - 建立應用程式

開啟命令提示符並執行以下命令:

C:\Users\username\Desktop>meteor create todo-app

要檢視應用程式,您需要使用meteor命令執行應用程式並訪問https://:3000

C:\Users\username\Desktop\todo-app>meteor

步驟 2 - 建立資料夾和檔案

我們將重構預設的檔案結構。讓我們建立一個client資料夾,在其中建立todo-app.html、todo-app.csstodo-app.js

C:\Users\username\Desktop\todo-app>mkdir client
C:\Users\username\Desktop\todo-app\client>touch todo-app.html
C:\Users\username\Desktop\todo-app\client>touch todo-app.js

我們還將建立一個包含server.jsserver資料夾。

C:\Users\username\Desktop\todo-app>mkdir server
C:\Users\username\Desktop\todo-app\server>touch server.js

最後,讓我們建立一個包含task-collection.js檔案的collections資料夾。

C:\Users\username\Desktop\todo-app>mkdir server
C:\Users\username\Desktop\todo-app\collections>touch task-collection.js

您可以在下圖中看到應用程式結構:

Meteor Todo App Structure

步驟 3 - client/todo-app.html

我們的第一步是為應用程式建立 HTML。我們需要一個輸入欄位,以便新增新的任務。任務將以列表的形式顯示,並具有刪除選中功能。我們還將具有顯示或隱藏已完成任務的功能。

<head>
   <title>Todo App</title>
</head>

<body>
   <h1>Todo List ({{incompleteCount}})</h1>

   <label class = "hide-completed">
      <input type = "checkbox" checked = "{{hideCompleted}}" />
      Hide Completed Tasks
   </label>

   <form class = "new-task">
      <input type = "text" name = "text" placeholder = "Add new tasks" />
   </form>

   <ul>
      {{#each tasks}}
         {{> task}}
      {{/each}}
   </ul>
</body>

<template name = "task">
   <li class = "{{#if checked}}checked{{/if}}">
      <button class = "delete">x</button>
      <input type = "checkbox" checked = "{{checked}}" class = "toggle-checked" />
      <span>{{username}} - {{text}}</span>
   </li>
</template>

步驟 4 - collections/task-collection.js

在這裡,我們將建立一個新的 MongoDB 集合,以便我們可以在伺服器端和客戶端使用它。

Tasks = new Mongo.Collection("tasks");

步驟 5 - server/server.js

我們將在伺服器端定義應用程式的方法。這些方法將從客戶端呼叫。在這個檔案中,我們還將釋出資料庫查詢。

// Publishing tasks from the server...

Meteor.publish("tasks", function () {
   return Tasks.find({});
});

// Methods for handling MongoDb Tasks collection data...

Meteor.methods({

   addTask: function (text) {

      Tasks.insert({
         text: text,
         createdAt: new Date(),
      });
   },

   deleteTask: function (taskId) {
      var task = Tasks.findOne(taskId);
      Tasks.remove(taskId);
   },

   setChecked: function (taskId, setChecked) {
      var task = Tasks.findOne(taskId);
      Tasks.update(taskId, { $set: { checked: setChecked} });
   }
});

步驟 6 - client/todo-app.js

這是主要的客戶端 JavaScript 檔案。此檔案也可以重構,但我們將在此處編寫所有客戶端程式碼。首先,我們訂閱在伺服器上釋出的task集合。然後,我們建立helpers來處理應用程式邏輯,最後,我們定義將呼叫伺服器方法的events

// Subscribing to the published tasks
Meteor.subscribe("tasks");

// Show/Hide functionality
Template.body.helpers({

   tasks: function () {

      if (Session.get("hideCompleted")) {

         // If hide completed is checked, filter tasks
         return Tasks.find({checked: {$ne: true}}, {sort: {createdAt: -1}});
      } else {
         
         // Otherwise, return all of the tasks
         return Tasks.find({}, {sort: {createdAt: -1}});
      }
   },

   hideCompleted: function () {
      return Session.get("hideCompleted");
   },

   incompleteCount: function () {
      return Tasks.find({checked: {$ne: true}}).count();
   }
});

// Events for creating new tasks and Show/Hide functionality.
// Calling methods from the server

Template.body.events({

   "submit .new-task": function (event) {
      event.preventDefault();
      var text = event.target.text.value;

      Meteor.call("addTask", text);
      event.target.text.value = "";
   },

   "change .hide-completed input": function (event) {
      Session.set("hideCompleted", event.target.checked);
   }
});

// Events for Deleting and Check/Uncheck functionality
Template.task.events({
   
   "click .toggle-checked": function () {

      // Set the checked property to the opposite of its current value
      Meteor.call("setChecked", this._id, ! this.checked);
   },

   "click .delete": function () {
      Meteor.call("deleteTask", this._id);
   }
});

步驟 7 - 部署

完成開發後,我們可以從命令提示符視窗部署應用程式。我們的應用程式的部署名稱將為my-first-todo-app

C:\Users\username\Desktop\todo-app>meteor deploy my-first-todo-app

我們可以開啟http://my-first-todo-app.meteor.com/來開始使用我們的應用程式。

Meteor Todo App Deploy

Meteor - 最佳實踐

我們已經在前面的章節中介紹了一些 Meteor 開發的最佳實踐。以下是在使用 Meteor 時需要注意的一些最佳實踐。

目錄結構

Meteor 應用程式的目錄結構沒有嚴格的規則。有關指南的更多資訊,請檢視 Meteor - 結構章節。

使用方法

在處理敏感資料時,應始終使用 Meteor - 方法,而不是直接從客戶端呼叫insert、updateremove

資料管理

使用 釋出和訂閱 方法來保護您的資料。如果您希望您的資料對所有客戶端可用,則可以使用null作為釋出名稱。釋出少量資料也將提高應用程式的效能。

驗證資料

您應該驗證將儲存在集合中的所有資料。最佳選擇之一是 collection2 包。此包簡化了伺服器端和客戶端驗證的設定。

最小化 Session

session變數是全域性變數,使用全域性變數違反了 JavaScript 的最佳實踐。

路由器

Meteor 路由有兩個最流行的選項。對於較小的應用程式,可以使用 Iron Router。它會在資料更改後自動重新執行。對於較大的應用程式,可以使用 Flow Router。此路由器讓您可以更自由地最佳化模板的重新渲染,代價是需要編寫少量樣板程式碼。

在選擇在應用程式中使用包之前,始終檢查該包是否定期更新。

廣告
© . All rights reserved.