使用Meteor,我试图了解何时使用服务器端Meteor.methods()
,同时仍保留即时UI更新。
来自Andrew Scala的introductory tutorial,他声称当您想要更新和修改数据库文档时应该使用Meteor.methods()
:
我们的想法是您定义服务器上的所有功能 修改和更新数据等危险的东西,然后让客户端 调用这些函数并获取常规函数之类的返回值。该 客户端永远不会看到实现,也不会亲自修改 数据。服务器完成所有工作。
遵循这个建议,我在我的代码中实现了这个:
服务器端:
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;
},
...
这很有效,但速度很慢。 UI不会像在客户端调用Movies.insert()
时那样立即更新。 docs表示,为了解决问题,您可以在客户端创建存根:
在客户端上调用方法定义与之关联的存根函数 同名的服务器方法。您不必为其定义存根 你的方法,如果你不想。在这种情况下,方法调用就是 比如在其他系统中进行远程过程调用,你必须等待 来自服务器的结果。
但这些存根应该是什么样的?它应该与服务器端方法基本相同吗?如果是这样,重点是什么?我正在寻找一个更全面的解释Meteor.methods()
的用法和目的,存根的点/用法及其实现。
修改: David Greenspan帮助澄清了meteor-talk上Meteor.methods()和存根的使用。
答案 0 :(得分:19)
这是另一个例子。
说你正在编写一个宾果游戏而你点击按钮来调用“house!”..在你可能称之为方法的点击事件中,例如。
Method.call("callHouse");
这将调用服务器方法:
// on the server
Meteor.methods({
callHouse: function () {
if (currentGame.isInProgress) {
currentGame.winner = this.userId;
currentGame.end();
}
}
});
如果你是第一个打电话给“house”的人,那么这个方法会把你标记为赢家..但是,让我们假装这个方法非常慢,而你的客户端应用程序正在等待......你肯定99%确定服务器会确认你是胜利者 - 你只想在没有等待的情况下更新用户的屏幕..在这种情况下实现客户端存根:
// on the client
Meteor.methods({
callHouse: function () {
currentGame.winner = Meteor.userId();
// add any other side-effects you expect to occur here
}
});
当服务器结果返回时,如果返回的数据与您在存根中设置的数据不同,它将更正它并相应地刷新屏幕。
答案 1 :(得分:12)
简而言之:
在推送到服务器的文件中定义一些方法(Meteor.methods),这些方法将在服务器上进行实际工作,在推送到客户端的文件中定义一些方法(Meteor.methods)以获得'瞬间& #39;客户端上的行为(例如加载指示符),直到服务器将结果更改推送回客户端
这是David的原帖:
嗨Ben,
原则上,一种方法可以对其执行完全不同的动作 客户端和服务器,例如显示加载指示器 客户端并与服务器上的远程API通信。打电话给 客户端上的Meteor.methods定义客户端行为,并调用 服务器上的Meteor.methods定义服务器行为。
对于在数据库上运行的方法,通常是相同的 实施将对两者都有效。客户端版本会影响 客户端数据库(浏览器端"缓存"订阅的文档 to)和服务器端版本影响真实数据库。当。。。的时候 客户听到回来,它会快速地回复"到服务器端的结果 突变;客户端数据库突变被丢弃(或 撤消,取决于你如何看待它)。如果是客户端方法 调用其他方法,这些辅助调用不远程调用 服务器。服务器端版本将调用相同的方法 是否适合服务器。
因此,您提供的任何客户端方法只是一个"模拟"和 并不一定准确(可能无法做到)。希望是 您通常免费获得模拟impl,因为它是 与服务器impl相同!
这会回答你的问题吗?
- 大卫
答案 2 :(得分:3)
如果您在客户端/服务器共享的文件上定义一个方法,例如/collections
,那么两者都可以访问它并自动存根?
所以:
/collections/houses.js
Meteor.methods({
callHouse: function () {
if (currentGame.isInProgress) {
currentGame.winner = this.userId;
currentGame.end();
}
}
});
这将可供客户端和服务器使用。如果它没有通过,服务器将自动拒绝客户端更新/恢复它。
答案 3 :(得分:3)
正如Daniel所说,您可以在文件上定义一个方法,该方法不在客户端或服务器目录中,并且可以在双方都可用。您还可以使用isSimulation
布尔值进行其他检查。例如,它可能看起来像这样:
Meteor.methods({
addMovie: function (movieData) {
if (!this.isSimulation) {
check(movieData, someAdditionaCheckinFunc);
}
Movies.insert(movieData);
}
})
因此,条件分支中的代码将仅在服务器上执行。