Das Framework, das ich oft im Vergleich zu Derby.js sehe, ist Meteor.js Ähnlich wie Derby kann es auch Ansichten in Echtzeit unter mehreren Clients aktualisieren, obwohl die oben beschriebene Methode möglicherweise etwas anders ist von Derby. Derby kann problemlos eine Vielzahl von Datenbanken verwenden, während Meteor nur in der Nähe von MongoDB ist. Tatsächlich ist die API für den Zugriff auf die Datenbank über den Client wie Mongoose dieselbe wie die, die Sie auf dem verwenden Server. Es kommt meinen Erwartungen sehr nahe.
Obwohl Meteor mittlerweile ein Framework mit einigen Mängeln und Kontroversen ist, scheint Meteor eine sehr interessante Wahl für die Erstellung von Anwendungen mit Echtzeitanforderungen zu sein. Mir persönlich gefällt die auf traditionellen Rückrufen basierende Programmierform immer noch Ich, aber in Derby fehlt es an robuster Dokumentation und einer großen Entwickler-Community, was zweifellos ein schwerer Schlag ist. Vielleicht wird sich das im Laufe der Zeit ändern, aber es wird immer noch viel langsamer sein als Meteor, weil Letzterer hat kürzlich 11 Millionen US-Dollar erhalten Diese finanzielle Förderung sichert Meteors Existenz und weitere Unterstützung, denn diese Finanzierung wird Meteor nur noch besser machen Wie man eine neue, realistische und dennoch einfache Meteor-Anwendung erstellt, basiert im Wesentlichen auf Toms Vimeo-Screencast. Der größte Unterschied zu Toms Vimeo-Screencast besteht in der Art und Weise, wie Ereignisse gehandhabt werden Code aus einem Meteor-Beispiel, ich werde Schritt für Schritt meine eigene Methode zum Senden einer Nachricht mit der Eingabetaste durchgehen. Fangen wir an.
Erstellen Sie eine Meteor-AnwendungEin großer Pluspunkt, den Derby und Meteor gemeinsam haben, sind ihre jeweiligen Befehlszeilentools. Im Gegensatz zu Derby, das das integrierte npm-Tool von Node verwendet, verwendet Meteor ein eigenes.
Führen Sie im Terminal (Mac OS X und Linux) den folgenden Befehl aus (Bitte stellen Sie sicher, dass Sie Node installiert haben, bevor Sie dies tun)
$curl https://install.meteor.com | /bin/sh
Um ein neues Projekt zu erstellen, gehen Sie zunächst in Ihr Arbeitsverzeichnis und führen Sie den folgenden Code aus. Dadurch wird ein Verzeichnis erstellt, das Meteor und ein grundlegendes Vorlagenprogramm enthält.
$meteor create chat
$cdchat$meteor Running on: http://localhost:3000/
So lange Sie möchten, können Sie den integrierten Meteor-Deploy-Befehl von Meteor verwenden, um Ihre Anwendung auf Meteors eigenem Server bereitzustellen
$meteor deploy my-app-name.meteor.com
In dem Ordner, der durch den Befehl „Meteor Create“ generiert wurde, können Sie verschiedene Dateien sehen. Wenn Sie wissen, wie man versteckte Dateien anzeigt, können Sie auch den .meteor-Ordner sehen. Dieser Ordner enthält Meteor selbst sowie MongoDB-Datendateien.
Im Stammordner Ihrer App sollten Sie diese drei Dateien sehen können: chat.html, chat.css und chat.js. Diese drei Dateien verfügen alle über eigene Beschreibungen. Die HTML-Datei enthält das Modell und das Erscheinungsbild der App, die durch chat.css definiert werden. Javascript-Dateien enthalten Skripte, die auf der Client- und Serverseite ausgeführt werden. Es ist wichtig, nichts in diese Skriptdatei einzufügen, wie z. B. Konfigurationsparameter und Passwörter, da diese jeder sehen kann, wenn er sich den Code Ihrer Anwendung ansieht.
Öffnen Sie die chat.js-Datei mit Ihrer bevorzugten Textbearbeitungssoftware. Persönlich verwende ich gerne Sublime Text2, weil dieses Tool einfach ist und über mehrere Mausstatus-Eingabeaufforderungen verfügt.
Sie können den folgenden Code in der Datei chat.js sehen:
if (Meteor.is_client) { Template.hello.greeting = function () { return "Welcome to chat."; }; Template.hello.events = { 'click input' : function () { // template data, if any, is available in 'this' if (typeof console !== 'undefined') console.log("You pressed the button"); } }; } if (Meteor.is_server) { Meteor.startup(function () { // code to run on server at startup }); }
Löschen Sie den gesamten Code in den Abschnitten Meteor.is_client und Meteor.is_server im if, sodass nur ein Abschnitt übrig bleibt:
if (Meteor.is_client) { }
Bevor wir offiziell mit der Arbeit an dieser Skriptdatei beginnen, müssen wir eine neue Ansicht zur Anzeige von Chat-Datensätzen erstellen und den Code im Body-Tag löschen der folgende Teil
<head> <title>chat</title> </head> <body> </body>
Meteor使用的模板系统与Mustache很相似.大括号{% raw %}{{}}{% endraw %}表示要呈现的内容. 通过简单地在两对大括号里添加内容如{% raw %}{{hello}}{% endraw %}, 模板系统会用hello这个变量的值来替换它. 后面会更详细的介绍.
注意到了在entryfield这个词前面有个大于号>了吗? 使用该符号来指定渲染哪一个模板.
<template name="entryfield"> <input type="text" id="name" placeholder="Name" /> <input type="text" id="message" placeholder="Your Message" /> </template>
在这个例子中,template标签有单个属性, 即模板的名字, 这就是我们要渲染的模板, 注意, 模板的名字要和body里的代码指定的模板名字一样 ({{> entryfield}})
查看浏览器, 你会发现页面已经刷新了, 输入框已经呈现出来了.
接下来, 在body里边添加另外的一个mutache标签用以渲染讯息列表
{{> messages}}
最后, 我们还需要新建一个名叫messages的模板. 在entryfield模板下面添加下面这段代码
<template name="messages"> <p> {{#each messages}} <strong>{{name}}</strong>- {{message}} {{/each}} </p> </template>
注意到each子句. 在Meteor中你可以使用如下的语法来遍历一个数组模板
{{#each [name of array]}} {{/each}}
使用each循环时,上下文会有所改变. 当引用变量的时候, 实际上你引用的是每一个数组元素的值.
例如,在我们的chat应用中, 我们遍历了数组模板"messages"里边的每个元素, 该数组可以像下面这样,
[ { "name": "Andrew", "message": "Hello world!" }, { "name": "Bob", "message": "Hey, Andrew!"" } ]
然后, 在each循环中, 你可以看到{% raw %}{{message}}{% endraw %}{% raw %}{{name}}{% endraw %}, 这会引用 每一个数组元素的值来替代(Andrew 和 Bob 替换 name, 以及各自的问候信息.)
当返回到你的浏览器, 你还看不到任何的改变. 因为讯息数组还没被传送到模板, 所以Meteor遍历不到任何东西来呈现.
你的chat.html最后应该是这样的
chat {{> entryfield}} {{> messages}} <template name="entryfield"> <input type="text" id="name" placeholder="Name" /> <input type="text" id="message" placeholder="Your Message" /> </template>{{#each messages}} {{name}}- {{message}}
{{/each}}
Javascript
从现在开始, 我们处理的大部分代码都是客户端代码, 所以, 除非特别说明, 以下的代码都是在if (Meteor.is_client)代码块中.
在我们编写展示讯息的代码之前,让我们先新建一个Collection. 从本质上讲, 这是一组Models. 换句话说, 在这个chat应用的环境下, Messages collection保存着整个聊天记录, 而每条讯息记录是一个Model.
在if语句前, 添加如下代码来初始化Collection:
Messages = new Meteor.Collection('messages');
因为我们希望这个Collection可以在客户端和服务端被创建, 所以我们把它写在了客户端代码块之外.
由于Meteor为我们做了大部分的工作, 要展示聊天记录是非常容易的. 只需要把下面的代码添加进if语句里边.
Template.messages.messages = function(){ return Messages.find({}, { sort: { time: -1 }}); }
让我们拆开来分析这段代码:
Template.messages.messages = function(){ … }
第一部分Template表示我们正在修改一个模板的行为.
Template.messages.messages = function(){ … }
第二部分messages是模板的名字, 表示是在修改哪一个模板. 例如,如果我们想要对"entryfield"模板做些什么, 只需把代码改成
Template.entryfields.variable = function(){ … }
(在这里, 请别这么做)
Template.messages.messages = function(){ … }
第三部分的这个messages代表的是一个这个模板里的一个变量. 还记得我们的each循环遍历messages吗? 这就是那个mesaages.
当你打开浏览器时, 页面还是没有什么改变. 这是意料之中的事, 因为我们只抓取的讯息, 而没有展示出来.
此时,你的chat.js应该是这样的. 是否很惊讶就只需在服务器写这么些代码我们就能展示一个实时的聊天记录应用.
Messages = new Meteor.Collection('messages'); if (Meteor.is_client) { Template.messages.messages = function(){ return Messages.find({}, { sort: { time: -1 }}); } }
在console里添加Message
这部分的内容是可选的, 当然它有助于你调试程序. 你可以直接跳过往下学习建立form来响应键盘事件(key press).
如果你想要测试你的讯息显示代码, 你可以手动插入一条记录到数据库. 打开你的浏览器控制台, 并输入如下:
Messages.insert({ name: 'Andrew', message: 'Hello world!', time: 0 })
这将会在数据库中新建一条记录, 如果正确的操作了的话,那浏览器就会即刻更新这条讯息在页面上.
消息表单
回到chat.js文件当中,我们会将供输入的form和数据库链接起来以接收用户聊天数据的提交。在底部添加下面的代码,不过注意要在if语句块中。
Template.entryfield.events = { "keydown #message": function(event){ if(event.which == 13){ // Submit the form var name = document.getElementById('name'); var message = document.getElementById('message'); if(name.value != '' && message.value != ''){ Messages.insert({ name: name.value, message: message.value, time: Date.now() }); name.value = ''; message.value = ''; } } } }
代码有点多,让我们再回顾一遍。你也许还记得,在Template后面的第二个单词决定了我们正在修改的是哪个模板。不过跟之前不同的是,我们写的代码是用来绑定数据库和messages模板的,我们正在修改的模板是entryfield。
这个模板中events的属性包含了一个object,events的属性按照下面的格式呈现:
"[eventname] [selector]"
例如,如果我们想为一个ID为hello的button绑定一个点击事件的话,我们会把下面的代码加入到events的个结构体当中。
"click #hello": function(event){ … }
在我们的例子当中,我们是将一个函数绑定到了ID为“message”的一个keydown事件当中。如果你还记得,这段代码早在我们在chat.html文件中建立模板的时候就已经设定好了。
在事件对象中,每个key都有一个函数作为它的值。这个函数在事件被调用时执行,其中事件对象作为第一个参数传递给该函数。在我们的app里,每当ID带有“message”的输入栏中有任意键被按下(keydown)时,该函数就被调用了。
函数内的代码相当简单。首先,我们检查回车键是否被按下(输入中有13的关键代码)。第二,我们通过ID取得两个输入栏的DOM元素。第三,我们检查并确保输入值不为空,以防止用户提交一个空的名字或信息(name or message)。
注意下面的代码很重要。这段代码是将message插入数据库。
Messages.insert({ name: name.value, message: message.value, time: Date.now() });
正如你看到的,这和我们插入到控制台的代码类似,但不是硬编码的数值,我们用的是DOM元素的值。此外,我们加入了当前时间,以保证聊天日志被正确的按时间排序。
最后,我们将两个输入的值简单的设为''以清空输入栏。
现在,如果你进入浏览器,你可以试着输入一个名字与信息到两个输入栏。按下回车以后,输入栏将被清除,一个新的消息会出现在你的输入字段的正下方。打开另一个浏览器窗口,导航到同一个URL(http://localhost:3000/)。试着键入另一个信息,而
正如你看到的,Meteor非常强大。不需要写一行明确更新消息日志的代码,新的信息显示出来并同步到多个浏览器和客户端。
总结
虽然Meteor工作起来非常酷,而且也有一些非常有用的应用支持它,比如Derby.js,但它是不成熟的。一个说明这一点例子就是,浏览文档并找找红色的引文。例如,关于MongoDB集合该文档做了如下陈述:
目前客户端被给予集合的完全写访问权限。它们可以执行任意的更新命令。一旦我们建立鉴权认证,你将能够限制客户端的直接插入,更新和删除。我们也在考虑校验器或者其他类似ORM的功能。
任何用户拥有完全的写访问权限是一个非常大的问题,因为对任何一个app产品——如果一个用户对你的整个数据库有写访问权限,这是一个相当大的安全问题。
看到Meteor(和Derby.js!)在像哪个方向前进是令人激动的,但是除非它成熟一点,它可能不是一个产品级应用的最好选择。期待那1100万美元资金能很好的利用起来。