meteor构建app程序

This is the second of a five-part series on building a Slack clone using Meteor. The aim of these tutorials are not just for you to blindly follow instructions, but it's our hope that you'll understand the thought process and reasoning behind the architecture.

这是有关使用Meteor构建Slack克隆的五部分系列的第二部分。 这些教程的目的不仅是让您盲目遵循说明,而且我们希望您能理解架构背后的思考过程和推理。

If you followed along with our previous article, you'd understand the killer features of Meteor, installed it on your machine and created the layout and styles of our apps using templates. We have also explained what Meteor does behind the scenes.

如果您继续阅读我们的上一篇文章 ,您将了解Meteor的杀手级功能,将其安装在您的计算机上,并使用模板创建应用程序的布局和样式。 我们还解释了Meteor在幕后所做的事情。

In this lesson, we will code the beef of the application and produce a fully-functional, live-updating chat room. to

在这一课中,我们将编写应用程序的牛肉 ,并产生一个全功能,实时更新的聊天室。 至

数据存储 (Data Storage)

First, we need to store our messages so they are persistent - so we can access them later. Doing so will also allow other clients connecting to our application to receive the updates in real time. It wouldn't be much fun if you just talk to yourself, would it?

首先,我们需要存储我们的消息以使其持久化-以便以后可以访问它们。 这样做还将允许连接到我们的应用程序的其他客户端实时接收更新。 如果你只是自言自语, 那不会很有趣, 不是吗?

To store our data, we need a database. The officially supported data storage system used in Meteor is MongoDB, although there are many contributed packages for MySQL (numtel:meteor-mysql), Postgres (austinrivas:meteor-postgresql, meteor-stream:meteor-postgres) and many more. You can also suggest additional database support on the Meteor Roadmap, there're ones for SQL and Redis specifically.

要存储我们的数据,我们需要一个数据库。 流星使用的官方受支持的数据存储系统是MongoDB ,尽管有许多MySQL贡献包( numtel:meteor-mysql ),Postgres( austinrivas:meteor-postgresqlmeteor-stream:meteor-postgres )等等。 您还可以在Meteor Roadmap上建议其他数据库支持,其中有专门针对SQL和Redis的支持 。

MongoDB fits well with what we are doing, and here are some reasons why.

MongoDB非常适合我们正在做的事情,这有一些原因。

MongoDB_Logo

Mongo与SQL (Mongo vs SQL)

Mongo is a NoSQL document database. A Mongo database consists of collections, which are similar to tables in SQL. A collection is literally a collection of documents, similar to a SQL table being a collection of rows.

Mongo是NoSQL文档数据库。 Mongo数据库由集合组成,这些集合类似于SQL中的表。 集合实际上是文档集合 ,类似于SQL 的集合。

But SQL has a flat key-value structure, Mongo allows much more flexibility because any valid JSON file* will make up a valid document. This means you can store nested structures - arrays inside objects, which are inside another array inside another object etc. - directly into the collection as a document (although heavy nesting is not necessarily a good idea!).

但是SQL具有平坦的键值结构,Mongo允许更大的灵活性,因为任何有效的JSON文件*都会构成有效的文档。 这意味着您可以将嵌套结构(对象内部的数组,位于另一个对象内部的另一个数组等内)作为文档直接存储到集合中(尽管重嵌套不一定是个好主意!)。

Because we model the messages, the users, the chatrooms all as objects (which may be nested), storing it in JSON format is a breeze. If you were to do this in SQL, you might have to create many tables and configure many relationships; there may also be performance issues as "joins are expensive".

因为我们将消息,用户,聊天室都建模为对象(可能是嵌套的),所以以JSON格式存储消息很容易。 如果要在SQL中执行此操作,则可能必须创建许多表并配置许多关系。 也可能存在性能问题,因为“连接昂贵”。

*Mongo actually stores your document as BSON, or Binary JSON, which can be viewed, in part, as an extension to JSON that allows for more data types, such as Date.

* Mongo实际上将您的文档存储为BSON或Binary JSON ,可以部分地将其视为JSON的扩展,以允许使用更多数据类型,例如Date。

对象关系映射 (Object-Relational Mapping)

Usually, when you work with a relational database in JavaScript, you'd interact with the database through an ORM (Object-relational mapping), and not with the database directly. This is because, as I said, the table structure of relational databases are flat, but for object-orientated JavaScript, we need to work with objects, which can have heavily-nested properties. The ORM will provide methods for us to query the database indirectly, saving us having to do complicated joins and also improve performance if used correctly.

通常,当您使用JavaScript使用关系数据库时,您将通过ORM(对象关系映射)与数据库进行交互,而不是直接与数据库进行交互。 正如我所说,这是因为关系数据库的表结构是扁平的,但是对于面向对象JavaScript,我们需要使用对象 ,它们可能具有大量嵌套的属性。 ORM将为我们提供间接查询数据库的方法,从而节省了我们进行复杂的联接的时间,并且如果使用正确,还可以提高性能。

If you've worked on a project involving Node.js or io.js with PostgreSQL, MySQL, MariaDB, SQLite or MSSQL, you might have come across the Sequelize ORM. If you've worked on the Laravel framework in PHP, you'd be greatly appreciative of their powerful Eloquent ORM.

如果您使用PostgreSQL , MySQL , MariaDB , SQLite或MSSQL从事涉及Node.js或io.js的项目,则可能遇到过Sequelize ORM 。 如果您使用过PHP的Laravel框架,那么他们强大的Eloquent ORM将不胜感激。

Sequelize logo

However, because we are working with a document database, all we have to do is simply make the object, and store the object, as-is, into our collection. Getting information is also just as easy, take the object and parse it without any transformation. Nested objects are fine without extra configurations, so there are no need for an ORM. This greatly reduces the complexity and the amount of code you need to write.

但是,由于我们正在使用文档数据库,因此我们所要做的只是简单地创建对象并将对象按原样存储到我们的集合中。 获取信息也同样容易,无需任何转换即可获取对象并对其进行解析。 嵌套对象不需要任何额外的配置即可,因此不需要ORM。 这大大降低了复杂性并减少了您需要编写的代码量。

无模式 (Schema-less)

Mongo is also schema-less. So if you'd like, you can insert objects with different properties into the collection and it will store it for you. For example, if you want to add an extra field to you messages; traditionally, you'd have to create a new column in your SQL table and fill the other entries with an empty string or NULL. Using MongoDB means you can add a property to one document without it affecting the other documents in your collection.

Mongo也没有架构。 因此,如果您愿意,可以将具有不同属性的对象插入集合中,它将为您存储它。 例如,如果您想在邮件中添加一个额外的字段; 传统上,您必须在SQL表中创建一个新列,并用空字符串或NULL填充其他条目。 使用MongoDB意味着您可以将一个属性添加到一个文档中,而不会影响您集合中的其他文档。

This does not mean Mongo cannot have a schema - a very common misconception! In fact, the Simple Schema Meteor package is one of the most popular packages, and provides a schema for Meteor collections. So Mongo is schema-less because a schema is not required or imposed onto the collections, not because it cannot have one.

并不意味着蒙戈不能有一个模式-一个非常普遍的误解! 实际上,“ 简单模式流星”软件包是最受欢迎的软件包之一,并且为“流星”集合提供了一个模式。 因此,Mongo无需使用架构,这是因为不需要或不将一种架构强加到集合上,而不是因为它不能拥有一个架构。

适合工作的正确工具 (Right Tools for the Right Job)

MongoDB is by no means the answer for everything. Some people jump on the bandwagon and use MongoDB for everything - this is not the way to go!

MongoDB绝不是一切的答案。 有些人随波逐流,并使用MongoDB进行所有操作-这不是路!

The reason why I made you read all that text is because we must remember - there's never a data storage system that can cater for everything, and you should pick the right tools for the right job. If your data structure is highly relational (meaning each field has many relations with other fields), then maybe SQL will be a better fit.

之所以让您阅读所有内容,是因为我们必须记住-从来没有一个数据存储系统可以满足所有需求,您应该选择正确的工具来完成正确的工作。 如果您的数据结构是高度相关的(意味着每个字段与其他字段有很多关系),那么SQL可能更适合。

馆藏 (Collections)

In MongoDB, our documents are stored inside collections. Defining a new collection is easy:

在MongoDB中,我们的文档存储在集合中。 定义新集合很容易:

Messages = new Mongo.Collection("messages");

One line is all it takes to create a new collection. But where do we put this line? Remember that one of the seven principles of Meteor is database everywhere, this means our collection should be available on both the client and the server.

创建新集合只需要一行。 但是我们把这条线放在哪里? 请记住,流星的七个原则之一是到处都有数据库 ,这意味着我们的集合应该在客户端和服务器上都可用。

Jog your memory back to the last article - if we want a file to be available on both client and server, we can actually store that file anywhere apart from inside the special directories (client/, server/, public/, private/, test/). It's my personal preference, or dare I say convention, to store it inside a collections/ directory on the application root directory.

唤起你的记忆回到了最后一篇文章 -如果我们希望一个文件可在客户端和服务器上,我们实际上可以在任何地方除了特殊目录(内存储文件client/server/public/private/test/ )。 将其存储在应用程序根目录上的collections/目录中是我的个人喜好,或者我敢说约定。

collections/messages.js

collections/messages.js

Messages = new Mongo.Collection("messages");

Now, we can open up another terminal and navigate to the root of the application. There, we will open up a Mongo shell

现在,我们可以打开另一个终端并导航到应用程序的根目录。 在那里,我们将打开一个Mongo外壳

$ meteor mongo
MongoDB shell version: 2.6.7
connecting to: 127.0.0.1:3001/meteor

And we can see that currently, the database is empty.

我们可以看到,当前数据库为空。

meteor:PRIMARY> show dbs
admin   (empty)
local   0.063GB
meteor  (empty)

That's because Meteor doesn't create the collection unless we are actually using it. But to test that it works, why don't you have a go at inserting some dummy data into it? Just change collection/messages.js to the following:

这是因为除非实际使用,否则Meteor不会创建该集合。 但是要测试它是否有效,为什么不去插入一些虚拟数据呢? 只需将collection/messages.js更改为以下内容:

Messages = new Mongo.Collection("messages");
Messages.insert({greeting: "hello"}, function() {});

If you query the database again, the collection is no longer empty, and you can see a new messages collection. Heck, you can even use db.collection.find() to get the message you just inserted!

如果再次查询数据库,则该集合不再为空,您将看到一个新的messages集合。 哎呀,您甚至可以使用db.collection.find()来获取刚刚插入的消息!

meteor:PRIMARY> show databases
admin   (empty)
local   0.063GB
meteor  0.031GB
meteor:PRIMARY> show collections
messages
system.indexes
meteor:PRIMARY> db.messages.find()
{ "_id" : "L84orvrSeZDCNEGWY", "greeting" : "hello" }

You can also use show dbs instead of show databases, and show tables instead of show collections

您还可以使用show dbs代替show databases ,并用show tables代替show collections

数据播种 (Data Seeding)

So our Meteor collections work. Now, let's seed our messages collection with some dummy data.

因此,我们的流星收集工作。 现在,让我们用一些虚拟数据为messages集合添加种子。

You can do so very simply by doing this:

您可以通过执行以下操作非常简单地执行此操作:

Meteor.startup(function () {if (Messages.find().count() === 0) {for( var i = 0; i < 10; i++ ) {Messages.insert({text: "A dummy message"});}}
});

Meteor.startup() is part of the Core API and allows you to define function(s) to run as soon as the server has been started. So here, we are simply checking whether the Messages collection is populated, and if not, insert 10 documents into it.

Meteor.startup()是Core API的一部分,它允许您定义要在服务器启动后立即运行的功能。 因此,在这里,我们只是在检查是否填充了Messages集合,如果没有,请向其中插入10个文档。

But using this method, all the messages are the same! You can of course specify an array of messages, but then that's hard work! Luckily for us, there are plenty of packages out there to help us fake some data!

但是使用这种方法,所有消息都是一样的! 您当然可以指定消息数组,但这很辛苦! 对我们来说幸运的是,这里有很多软件包可以帮助我们伪造一些数据!

假装 (Faking it)

You might have previously seeded your database with Faker, a name that's associated with tools that generate fake data such as words, names, phone number, emails and pretty much anything you can think of. It has a version for Node, one of PHP, one for Perl and one for Ruby; this is of course not an exhaustive list.

您之前可能已经用Faker播种了数据库,该名称与生成伪造数据的工具(例如单词,姓名,电话号码,电子邮件以及几乎所有您能想到的东西)相关联。 它有一个Node版本,一个PHP版本 ,一个Perl版本和一个Ruby版本 ; 这当然不是详尽的清单。

But Meteor also comes with its own package - anti:fake, which works well alongside dburles:factory. They are not feature-rich as the Faker packages, but it is enough for our use, and it will also give you an opportunity to learn how to install Meteor packages.

但是Meteor还带有自己的软件包anti:fake ,与dburles:factory一起dburles:factory效果很好。 它们不像Faker软件包那样功能丰富,但足以供我们使用,它也将为您提供学习如何安装Meteor软件包的机会。

Meteor has its own packages repository - Atmosphere. Head over there now and search for fake. And select the anti:fake package.

流星有自己的软件包存储库-Atmosphere 。 现在去那边寻找fake 。 并选择anti:fake软件包。

To install anti:fake, just run the meteor add command.

要安装anti:fake ,只需运行meteor add命令。

meteor add anti:fake

The first part of the package name is, by convention, the package author, and the latter part is the name of the package. You'll see the package being added successfully.

按照惯例,程序包名称的第一部分是程序包作者,而后半部分是程序包的名称。 您会看到该软件包已成功添加。

anti:fake  added, version 0.4.1
anti:fake: Random text and data generator

If you now look inside .meteor/packages and .meteor/versions, you'll see an entry for the anti:fake package. You should check these files into the repository, so people who clone your application can download the same packages (and version) as you.

如果现在查看.meteor/packages.meteor/versions ,您将看到anti:fake软件包的条目。 您应该将这些文件检入资源库,以便克隆您的应用程序的人可以下载与您相同的软件包(和版本)。

Next, do the same with the dburles:factory package.

接下来,对dburles:factory软件包执行相同的dburles:factory

Now we have the tools, let's create a seeder.js file inside our server/ directory, where we will insert dummy data into our collection when the server starts. For now, anyone can post a message (which means, in effect, everyone posts as the same user).

现在我们有了工具,让我们在server/目录中创建seeder.js文件,在服务器启动时,我们将在其中将虚拟数据插入到集合中。 目前,任何人都可以发布一条消息(实际上,这意味着每个人都以同一用户的身份发布)。

Meteor.startup(function() {Factory.define('message', Messages, {text: function() {return Fake.sentence();}});// Add this if you want to remove all messages before seedingMessages.remove({});if (Messages.find({}).count() === 0) {_(10).times(function(n) {Factory.create('message');});}
});

And now, query the messages collection again using meteor mongo, and find it filled with dummy data!

现在,使用meteor mongo再次查询messages集合,并发现其中充满了伪数据!

meteor:PRIMARY> db.messages.find()
{ "_id" : "f7obDSzes2sz7KFHM", "text" : "Is remo esy ingment warddifulercom comsurco caldecondie addis eddi tyentheac eris." }
{ "_id" : "gjAdHexFzNWEvqt8L", "text" : "Inble minly erthebe conna inger." }
{ "_id" : "wmGfZnDkfGYdDvAE5", "text" : "Eslecin deelofthe suren therey dia cy in inomander moo." }
{ "_id" : "Ft5Xa4eHmy7Cpm5Lh", "text" : "Canthees se ter iningra lybeper torterlyextion dis noenan la esgenthetytion fimentreerde." }
{ "_id" : "g7RkhEkGZnz6MP69m", "text" : "E ament tytaly comastiono terthe." }
{ "_id" : "FagjoGcmsBL5ovpFz", "text" : "Conmentcallightal atra in ytureci talex tainestmis thethe." }
{ "_id" : "jYZxTev3HkcG5LkMR", "text" : "Titheaf ingex et ied pitiono." }
{ "_id" : "LFZ6eXawjsoGf3y29", "text" : "Tionre reees lylydicomters ersit tyre tinlyar." }
{ "_id" : "QT6KHmkWcfMtBT4mH", "text" : "Confac calde tuyingoras tirire re lyertionar." }
{ "_id" : "u7EA6vCD7QicRyM3C", "text" : "Uedin secalcon sii anaterpar dencom yernun ertheno." }

If you want to delete your entire database and start from scratch, quit your application and run meteor reset. Be careful as this will remove all the data in the database.

如果要删除整个数据库并从头开始,请退出应用程序并运行meteor reset 。 请小心,因为这将删除数据库中的所有数据。

Next, let's use this dummy data instead of hard-coding it into our template(s) or helper(s). But before we do, Christmas came early for all of us!

接下来,让我们使用此虚拟数据,而不是将其硬编码到我们的模板或帮助器中。 但是在我们这样做之前,圣诞节对我们所有人来说都太早了!

机器人蒙哥 (RoboMongo)

meteor mongo is great, but wouldn't it be better to have a GUI though? Well, here's a little gem called Robomongo!

meteor mongo很棒,但是拥有GUI会更好吗? 好吧,这是一个名为Robomongo的小宝石!

Robomongo is the MongoDB management tool. It has a great GUI, with different view modes. It also embeds the same JavaScript engine that powers MongoDB's shell - this means you can run shell commands from within Robomongo, but now with the help of autocomplete and syntax highlighting.

Robomongo MongoDB的管理工具。 它具有出色的GUI ,具有不同的查看模式。 它还嵌入了支持MongoDB Shell的同一JavaScript引擎-这意味着您可以从Robomongo中运行Shell命令,但是现在借助自动完成功能和语法高亮显示。

If you want to connect to a remote database, you can do so; and if you don't want to open up port 27017, you can even connect through SSH!

如果要连接到远程数据库,则可以这样做; 如果您不想打开端口27017 ,甚至可以通过SSH连接!

Note, however, the current version of Robomongo does not fully-support MongoDB 3.x. You can keep track of the issue on GitHub.

但是请注意,当前版本的Robomongo并不完全支持MongoDB3.x。 您可以在GitHub上跟踪问题。

Go ahead and download it for your platform now!

继续下载,现在就为您的平台下载!

Now, let's use Robomongo to see our new collection.

现在,让我们使用Robomongo来查看我们的新系列。

$ robomongo

The GUI of Robomongo will pop up asking you to connect to a database. By default, Meteor will run on port 3000 and the MongoDB that comes with Meteor will run on port 3001.

将弹出Robomongo的GUI ,要求您连接到数据库。 默认情况下,Meteor将在端口3000上运行,Meteor随附的MongoDB将在端口3001上运行。

So on the popup window that appears, click on 'Create' to configure a connection to MongoDB.

因此,在出现的弹出窗口中,单击“创建”以配置与MongoDB的连接。

Next, give your connection a name so you can recognize it later, I usually choose the name of the application as the connection name.

接下来,给您的连接起一个名字,以便您以后可以识别它,我通常选择应用程序的名称作为连接名。

Press 'Save'. Select your connection and click 'Connect'

按“保存”。 选择您的连接,然后单击“连接”

And now, navigate down the tree and double-click on the messages collection, where all the documents will appear on your right!

现在,在树上导航并双击messages集合,所有文档将出现在您的右边!

If you already have MongoDB running on your machine and you want to use that instead, just add the environment variable MONGO_URL=mongodb://localhost:27017/meteor, assuming your Mongo installation is running on the default Mongo port of 27017 and the database name is meteor.

如果您已经在计算机上运行了MongoDB,而您想使用它,则只需添加环境变量MONGO_URL=mongodb://localhost:27017/meteor ,假设您的Mongo安装正在默认的Mongo端口27017和数据库上运行名字是meteor

使用集合 (Using Collections)

OK, back to our application. Remember from our previous article, we had an array defining all our messages in client/app.js.

好,回到我们的应用程序。 记住,在上一篇文章中,我们有一个数组定义了client/app.js所有消息。

Template.messages.helpers({messages: [{ text: "All these messages" },{ text: "Uses the same template" },{ text: "But have a different data context" },{ text: "It's why these messages are all different!" },{ text: "Hey!" },{ text: "What's up man!" },{ text: "Hello" }]
});

But now, we can use our Messages collection instead! There are many methods available to interact with collections, and you can find them in the official documentation. For now, we only need to use two - collection.find() to retrieve documents, and collection.insert() to add a document.

但是现在,我们可以改用我们的Messages集合! 与集合进行交互的方法很多,您可以在官方文档中找到它们。 现在,我们只需要使用两个collection.find()来检索文档,以及collection.insert()来添加文档。

Now, replace the entire client/app.js with the following

现在,将整个client/app.js替换为以下内容

Template.messages.helpers({messages: Messages.find({})
});

When I passed in an empty object (or pass nothing in at all) it will retrieve all the records in the collection. So now when your application refreshes, you should see the list of messages you inserted into the collection! Try it!

当我传入一个空对象(或什么都不传入)时,它将检索集合中的所有记录。 因此,当您的应用程序刷新时,您应该会看到插入到集合中的消息列表! 试试吧!

Well that didn't work...let's open up the console and find out why!

好吧,那没用...让我们打开控制台,找出原因!

Uncaught ReferenceError: Messages is not defined

But we did define it in collections/messages.js, what's the deal? The deal is a little thing called load order.

但是我们确实collections/messages.js定义了它,这是怎么回事? 这笔交易叫装载订单

Previous documentation on file load order was a little vague, and led to much confusion. So I took the liberty and re-written the Meteor documentation on file load order, in the hope that it makes more sense.

以前有关文件加载顺序的文档有些含糊,并引起 了 很多 混乱 。 因此,我自由了下来,并按照文件加载顺序重写了Meteor文档 ,希望这样做更有意义。

These are the five rules, which should be applied in order:

这些是五个规则,应按顺序应用:

  1. HTML template files are always loaded before everything else
    HTML模板文件总是先加载
  2. Files beginning with main. are loaded last
    以main开头的文件。 最后加载
  3. Files inside any lib/ directory are loaded next
    接下来将加载任何 lib /目录中的文件
  4. Files with deeper paths are loaded next
    接下来加载路径更深的文件
  5. Files are then loaded in alphabetical order of the entire path
    然后按照整个路径的字母顺序加载文件

Going back to our malfunctioning application, because the entire path of our client/app.js is before the path for collections/messages.js alphabetically, the client/app.js file is being loaded before collections/messages.js, hence the error we get.

回到我们有故障的应用程序,因为我们的client/app.js的整个路径按字母顺序位于collections/messages.js的路径之前,所以将client/app.js文件加载 collections/messages.js 之前 ,因此出现错误我们得到。

Let's experiment a little and rename our collections directory to aaaaa. You'll find the messages coming back again, because aaaaa... comes before client... alphabetically!

让我们做一些实验,并将collections目录重命名为aaaaa 。 您会发现消息再次返回,因为aaaaa...client...之前client...按字母顺序!

All messages are showing again after tinkering with load order

But that's a really stupid name, so let's utilize rule #3 and change collections/messages.js to lib/collections/messages.js instead. Great! Everything works!

但这是一个非常愚蠢的名称,因此让我们利用规则3,将collections/messages.js更改为lib/collections/messages.js 。 大! 一切正常!

加入收藏 (Adding to Collection)

Adding to the collection is just as easy. Now, instead of manually appending a block of HTML onto the page, we just add the message to the Messages collection. (We're also checking that the input box is not empty before inserting)

添加到收藏集也一样容易。 现在,我们无需将HTML块手动添加到页面上,而是将消息添加到Messages集合中。 (我们还在插入之前检查输入框是否为空)

Template.footer.events({'keypress input': function(e) {var inputVal = $('.input-box_text').val();if(!!inputVal) {var charCode = (typeof e.which == "number") ? e.which : e.keyCode;if (charCode == 13) {e.stopPropagation();Messages.insert({text: $('.input-box_text').val()});$('.input-box_text').val("");return false;}    }}
});

Let's try another little experiment. We will restart our application so we get our seeded messages again. We will now submit a new message. After this, we will quit our meteor process on the server (e.g. pressing Ctrl + C)

让我们尝试另一个小实验。 我们将重新启动应用程序,以便再次获得种子消息。 现在,我们将提交一条新消息。 之后,我们将退出服务器上的meteor过程(例如,按Ctrl + C

If you look in the console now, you'll see several messages like this:

如果您现在在控制台中查看,您将看到以下几条消息:

GET http://localhost:3000/sockjs/info?cb=w8_t8rtb3s net::ERR_CONNECTION_REFUSED

Now, let's type in a second message into the box and hit Enter. Then, restart meteor. You'll see two things:

现在,让我们在框中输入第二条消息,然后按Enter。 然后,重新启动meteor 。 您会看到两件事:

  1. The second message appeared on your screen immediately after you pressed the carriage return key , even when the server is down
    按下回车键↵之后 ,即使服务器关闭,第二条消息也会立即出现在屏幕上
  2. You're able to recover the second message but the first one is gone (rightly so because in our seeder we erase all previous messages)
    您可以恢复第二条消息,但是第一条消息不见了(正确的原因是,在我们的播种机中,我们删除了所有先前的消息)

This is possible because of Meteor's minimongo.

由于流星的minimongo,这是可能的。

Minimongo (Minimongo)

Minimongo can be seen as a simple version of MongoDB that sits on the client. When we inserted into our Messages collection, we are inserting into this local version of Mongo, as well as the remote version.

Minimongo可以看作是位于客户端的MongoDB的简单版本。 当我们插入Messages集合时,我们将插入此本地版本的Mongo和远程版本。

React性 (Reactivity)

In Meteor, reactivity works by it detecting a change in a data source, and then re-running some code to recompute the new values. Here're a list of reactive data sources:

在Meteor中,React性通过检测数据源中的更改,然后重新运行一些代码以重新计算新值而起作用。 这是React性数据源的列表:

  • Session variables
    会话变量
  • Database queries on Collections
    对集合的数据库查询
  • Meteor.status
    Meteor.status
  • The ready() method on a subscription handle
    订阅句柄上的ready()方法
  • Meteor.user
    Meteor.user
  • Meteor.userId
    Meteor.userId
  • Meteor.loggingIn
    Meteor.loggingIn

Don't worry about most of them, but just notice that database queries are a reactive data source. This means as soon as the local database updated, minimongo will detect this change and triggers a recomputation that leads to our helper getting the updated values and reactively adding the message onto the screen. This is why as soon as you hit Enter, the message appeared on your screen immediately.

不必担心其中的大多数,而只需注意数据库查询是一种React式数据源。 这意味着在本地数据库更新后,minimongo将立即检测到此更改并触发重新计算,从而导致我们的助手获取更新后的值并将消息以React方式添加到屏幕上。 这就是为什么当您按下Enter键后,消息立即出现在屏幕上的原因。

This reactivity is achieved through Blaze, which in turns uses Tracker. But which is too much to get into that right now. Just understand that Tracker provides reactivity, and Blazes uses the updated information to update the view (or user interface), all done without polling for changes periodically.

这种React性是通过Blaze实现的,后者又使用了Tracker。 但是,现在无法解决这一问题。 只需了解Tracker提供了React性,并且Blazes使用更新的信息即可更新视图(或用户界面),所有这些操作都无需定期轮询更改。

Because Meteor is modular, you're not tied down to Blaze. You can use Meteor with React and Angular, for example. If you want to learn how to do that, this video on React + Meteor, and this talk on Angular + Meteor, may interests you.

由于Meteor是模块化的,因此您不必局限于Blaze。 例如,您可以将Meteor与React和Angular一起使用。 如果您想学习如何做,这个关于React + Meteor的视频以及这个关于Angular + Meteor的演讲可能会让您感兴趣。

React JS

延迟补偿 (Latency Compensation)

Somewhat related to reactivity, Meteor implements latency compensation. This means Meteor will update the UI even without confirmation from the server, just like our message. But then when the 'real' data comes back from the server, the UI is updated if, and only if, it needs to. This is extremely useful to providing good user experience when you are very sure of the expected outcome, as it stops the user having to appear to wait for confirmation.

与React性某种程度上,Meteor实现了延迟补偿。 这意味着Meteor即使在没有服务器确认的情况下也将更新UI,就像我们的消息一样。 但是,当“真实”数据从服务器返回时,仅在需要时才更新UI。 这是为了提供良好的用户体验是非常有用的,当你预期的结果非常肯定,因为它阻止用户不必出现等待确认。

Here, we know, by the design of our application, that messages by anyone will be inserted into the database, so that's a good use case. Later on, when we deal with users and authentication, maybe the insert will not be successful, but then in those case, we can update the UI in a logical fashion, such as making the text red to indicate failure, instead of just removing it.

在这里,通过应用程序的设计,我们知道任何人的消息都将插入数据库,因此这是一个很好的用例。 稍后,当我们处理用户和身份验证时,也许插入不会成功,但是在那种情况下,我们可以以逻辑方式更新UI,例如将文本变为红色表示失败,而不仅仅是删除它。 。

How useful latency compensation is depends on the use case and your implementation. But it's there as a feature should you need it.

延迟补偿的有用程度取决于用例和您的实现。 但是它是您需要时的一项功能。

离线使用 (Offline Use)

Meteor may also be useful for brief offline use. As you saw, the message we sent when the server was down didn't go through immediately, but when it booted up again, the client will try to communicate with it and pass up any changes to the data it received til then. That's why the second message showed up.

流星对于短暂的离线使用也可能有用。 如您所见,当服务器关闭时,我们发送的消息并没有立即通过,但是当服务器再次启动时,客户端将尝试与之通信,并将对所接收数据的任何更改向上传递,直到此为止。 这就是为什么出现第二条消息的原因。

But this is also the case when the client loses connection with the server. As soon as the client gets back this connection, those messages will still be sent to the server.

但是,当客户端与服务器失去连接时,也是如此。 一旦客户端恢复此连接,这些消息仍将发送到服务器。

发布和订阅 (Publish & Subscribe)

By default, Meteor comes with the autopublish package, which automatically publishes all collections in the entire database. This means the client have access to (is subscribed to) all the collections on the server.

默认情况下,Meteor附带有autopublish软件包,该软件包会自动在整个数据库中发布所有集合。 这意味着客户端可以访问(预订)服务器上的所有集合。

So if we open up two different browsers (or the same browser but one is in 'private' mode). When we insert a message from one client, the change is seen on the other. This is because every client is automatically subscribed to the collections, and as soon as the collection updates, all the clients update also.

因此,如果我们打开两种不同的浏览器(或相同的浏览器,但其中一种处于“私有”模式)。 当我们从一个客户端插入消息时,在另一客户端上看到更改。 这是因为每个客户端都自动订阅了该集合,并且一旦集合更新,所有客户端也会更新。

Updates across different clients

Obviously, this have huge security implications in a real chatroom because we don't want people to read our private chats! So in the next article, we will explore the idea of adding users to our application, and using publication and subscription so users can only see certain rooms.

显然,这在真实的聊天室中具有巨大的安全隐患,因为我们不希望人们阅读我们的私人聊天! 因此,在下一篇文章中,我们将探讨将用户添加到我们的应用程序中以及使用发布和订阅的想法,以便用户只能看到某些房间。

翻译自: https://scotch.io/tutorials/building-a-slack-clone-in-meteor-js-real-time-data

meteor构建app程序

meteor构建app程序_在Meteor.js中构建Slack克隆:实时数据相关推荐

  1. meteor构建app程序_在Meteor.js中构建Slack克隆(第5部分):流星部署

    meteor构建app程序 This is the fifth, and last, of a five-part series on building a Slack clone using Met ...

  2. node mongoose_如何使用Express,Mongoose和Socket.io在Node.js中构建实时聊天应用程序

    node mongoose by Arun Mathew Kurian 通过阿伦·马修·库里安(Arun Mathew Kurian) 如何使用Express,Mongoose和Socket.io在N ...

  3. mpvue 微信小程序_使用Vue.js开发微信小程序:开源框架mpvue解析

    戳蓝字"CSDN云计算"关注我们哦! 作者 | 成全 责编 | 阿秃 转自 | 美团技术团队企业博客 前言 mpvue是一款使用Vue.js开发微信小程序的前端框架.使用此框架,开 ...

  4. figma设计_如何在Figma中构建设计入门套件(第1部分)

    figma设计 Figma教程 (Figma Tutorial) Do you like staring at a blank canvas every time you start a new pr ...

  5. react入门代码_如何在React中构建温度控制应用程序-包括提示和入门代码

    react入门代码 我们正在建立的 (What we're building) In this beginner React project, we're going to learn how to ...

  6. 全阶滑模观测器程序_滑模观测器的构建方法与流程

    本发明属于滑模控制技术领域,特别是涉及一种滑模观测器的构建方法. 背景技术: 现有技术中利用线性积分法计算驱动轴扭矩时,会受到车轮转速传感器.电机旋变误差的影响,转速传感器信号噪声.外界干扰等也会由于 ...

  7. 什么叫静态构建版本号码_为什么要使用GatsbyJS构建静态网站

    什么叫静态构建版本号码 by Ajay NS 由Ajay NS 为什么要使用GatsbyJS构建静态网站 (Why you should use GatsbyJS to build static si ...

  8. react网格生成_如何在React中构建实时可编辑数据网格

    react网格生成 by Peter Mbanugo 彼得·姆巴努戈(Peter Mbanugo) 如何在React中构建实时可编辑数据网格 (How to Build a Real-time Edi ...

  9. node.js中模块_在Node.js中需要模块:您需要知道的一切

    node.js中模块 by Samer Buna 通过Samer Buna 在Node.js中需要模块:您需要知道的一切 (Requiring modules in Node.js: Everythi ...

最新文章

  1. SoftReference
  2. MySQL5.7 Replication主从复制配置教程
  3. 单实例单向rac搭建gg流
  4. java面向对象基础代码_JAVA基础知识点之Java面向对象
  5. js最小化浏览器_「译」解析、抽象语法树(ast) +如何最小化解析时间的5个技巧...
  6. python判断ip是否可以ping通
  7. 创建wincc项目提示无法连接到服务器,wincc 项目管理器 服务器不可用 无法连接到服务器...
  8. 使用Jena-TDB存储RDF本体、知识图谱文件
  9. 对“黑暗森林”的质疑和讨论(总结各家言论)
  10. mysql数据库技术与项目课后答案_数据库技术与应用mysql版答案
  11. oracle连接失败的原因总结
  12. 丁香园开源接口管理系统 - API Mocker
  13. TimeZone.getTimeZone(GMT-8:00)和TimeZone.getTimeZone(America/Los_Angeles)的区别
  14. RTX操作系统教程[02]
  15. 禁用计算机通信端口,win7/win10系统电脑禁用445端口的详细教程
  16. java解析json文件并保存到mysql数据库
  17. 在URLOS中运行Ghost博客docker镜像
  18. html5 dreamlive,熠熠闪耀的ENSEMBLE! DREAM LIVE 5th Tour Stargazer即将开演
  19. 计算机办公软件应用补贴,计算机办公软件应用(WordExcelPowerPoint)
  20. mysql客户端如何建库_mysql建库建用户命令

热门文章

  1. luogu1010:幂次方
  2. Office 2016系列下载地址
  3. Android 按钮设置边框实例
  4. NextVR踏入足球锦标赛直播 更能身历其境
  5. delphi7 获取计算机名,Delphi中根据IP地址得到主机名
  6. 甘特图,看这篇就够了
  7. 【002】EIS测试_#LIB
  8. python遗传算法实例:求一元二次方程实例
  9. Windows命令之netstat命令
  10. 关于日志造成的频繁的IO