何时使用Meteor.methods和利用存根
使用meteor,我试图了解何时使用服务器端Meteor.methods()
同时仍然保持即时UI更新。
从Andrew Scala的入门教程中 ,他声称当你想更新和修改你的数据库文档时应该使用Meteor.methods()
:
这个想法是,你定义了服务器上的所有function,如修改和更新数据等危险的东西,然后让客户端调用这些function,并得到像常规函数的返回值。 客户从来没有看到实施,也不亲自修改数据。 服务器完成所有工作。
遵循这个build议,我在我的代码中实现了这个:
服务器端:
Meteor.methods({ addMovie: function(data) { var movie = Movies.insert({name: data}); return movie; }, ...
客户端:
Template.movies.events = ({ 'click #add-movie': function(e) { var name = document.getElementById('movie-name').value; Meteor.call('addMovie', name); return false; }, ...
这有效,但速度很慢。 如果您在客户端调用Movies.insert()
,UI将不会立即更新。 文档指出,为了纠正这个问题,你可以在客户端创build存根:
客户端调用方法定义了与同名服务器方法相关的存根函数。 如果你不想要,你不必为你的方法定义一个存根。 在这种情况下,方法调用就像其他系统中的远程过程调用一样,您将不得不等待来自服务器的结果。
但是这些存根应该是什么样的? 它应该基本上看起来像服务器端方法一样吗? 如果是这样,那有什么意义呢? 我正在寻找Meteor.methods()
的用法和目的的更全面的解释,存根的使用和使用,以及它们的实现。
编辑:大卫格林斯潘已经帮助澄清Meteor.methods()和stream行谈话的存根(stub)的使用。
这是另一个例子。
说你正在写一个宾果游戏,你点击button来调用“房子!”..在点击事件中,你可能会调用一个方法,例如
Method.call("callHouse");
这将调用服务器方法:
// on the server Meteor.methods({ callHouse: function () { if (currentGame.isInProgress) { currentGame.winner = this.userId; currentGame.end(); } } });
如果你是第一个打电话给“房子”的方法,那么这个方法将会标志着你是赢家。但是,让我们假装这个方法非常慢,你的客户端应用程序正在等待。你确信服务器会确认你是获胜者 – 您只是想更新用户的屏幕而不用等待。在这种情况下实现客户端存根:
// on the client Meteor.methods({ callHouse: function () { currentGame.winner = Meteor.userId(); // add any other side-effects you expect to occur here } });
当服务器结果返回时,如果返回的数据与在存根中设置的数据不同,则会对其进行更正并相应地刷新屏幕。
简而言之 :
在推送到服务器的文件中定义一些方法(Meteor.methods),这些方法将在服务器上进行实际工作,在推送到客户端的文件中定义一些方法(Meteor.methods)以在客户端上获得“即时”行为如加载指示器),直到服务器将产生的更改推回客户端
这是David的原文:
嗨,本,
原则上,一种方法可以在客户端和服务器上执行完全不同的动作,例如在客户端上显示一个加载指示符,并与服务器上的一个远程API进行交谈。 调用客户端上的Meteor.methods定义客户端行为,并调用服务器上的Meteor.methods定义服务器行为。
对于在数据库上运行的方法,通常相同的实现可以同时执行。 客户端版本影响客户端数据库(订阅文档的浏览器端“caching”),服务器端版本影响真实数据库。 当客户端收到回应时,它会“捕捉”服务器端突变的结果; 客户端数据库突变将被丢弃(或取消,取决于您如何思考)。 如果客户端方法调用其他方法,则这些辅助调用不会远程服务器。 服务器端版本将会调用服务器上相同的方法,或者不会,因为它认为合适。
因此,您提供的任何客户端方法impl只是一个“模拟”,并不一定是准确的(它可能无法)。 希望是你通常得到免费的模拟impl,因为它与服务器impl是一样的!
这回答了你的问题了吗?
– 大卫
如果你定义一个方法在客户端/服务器共享的文件像/collections
不会被它们都可以访问和自动存根?
所以:
/collections/houses.js
Meteor.methods({ callHouse: function () { if (currentGame.isInProgress) { currentGame.winner = this.userId; currentGame.end(); } } });
这将可用于客户端和服务器。 如果不通过,服务器将自动拒绝客户端更新/恢复它。
正如丹尼尔说的,你可以在文件上定义一个不在客户端或服务器目录中且在双方都可用的方法。 您还可以使用isSimulation
布尔值进行其他检查。 例如,它可能看起来像这样:
Meteor.methods({ addMovie: function (movieData) { if (!this.isSimulation) { check(movieData, someAdditionaCheckinFunc); } Movies.insert(movieData); } })
因此,条件分支中的代码将仅在服务器上执行。