我从客户端执行Meteor.call
到Meteor.methods
方法,并且作为console.log
项,它们在命令提示符和浏览器控制台中都被记录。
这个问题是它实际上似乎是在客户端执行 - 它无法访问正确的实体。虽然我在命令提示符下没有出现任何错误,但这是客户端显示的内容:
在模拟调用' createInvite'的效果时出现异常 Meteor.makeErrorType.errorClass {error:" not-found&#34 ;, reason: " evaluator_invite__entity_not_found",详情:undefined,message: " evaluator_invite__entity_not_found [not-found]",errorType: " Meteor.Error" ...}错误:evaluator_invite__entity_not_found [not-found] 在Meteor.methods.createInvite(http://localhost:3000/lib/collections/invites.js?505cdea882e0f829d521280c2057403ec134b075:38:15)
它实际上是在客户端运行吗?这个错误应该存在吗?
答案 0 :(得分:5)
如果全局定义,预计Meteor方法将在两个环境上运行,这允许一个很好的功能,称为延迟补偿。
整个延迟补偿概念是偏离主题的,但基本上它意味着模拟客户端服务器实际上会做什么,就像在数据库中直接插入文档来设计流体UX一样。您实际上是在通过消除网络延迟来使客户端体验超级响应之前预测服务器行为。
此示例可能是在用户提交后立即在数据库中插入注释。在这种情况下,Meteor方法调用在服务器上执行并且客户端将共享相同的代码。
有时,在设计负责发送电子邮件的方法时,提供仅客户端模拟或“存根”完全没有意义。
有时候共享代码的某些部分是有意义的,但是您需要访问特定于环境的对象:例如,插入注释的方法可能会在服务器上使用Email.send
来通知作者注释已被注释在他的帖子上添加了。
Meteor.methods({
insertComment: function(comment){
check(comment, [...]);
if(! this.isSimulation){
Email.send([...]);
}
return Comments.insert(comment);
}
});
最终,您必须根据方法的行为方式对代码进行不同的构造。
对于仅限服务器的方法,请在server
目录下定义它们,不要与客户端对应。
对于可在两种环境中共享完全相同代码的共享方法,只需全局定义即可。
对于略有不同的共享方法,您可以使用Meteor.isClient
/ Meteor.isServer
或仅方法属性isSimulation
来检查当前环境并相应地执行特定代码。 / p>
对于共享很少甚至没有代码的共享方法,我个人使用一种模式,我在客户端和服务器环境中定义Meteor方法并处理共享行为,如检查参数有效性,然后我调用一个函数负责实际上是为了实现正确的行为。
lib/method.js
Meteor.method({
method: function(args){
check(args, [...]);
//
return implementation(args);
}
});
诀窍是在客户端和服务器上单独定义implementation
,根据上下文,将调用正确的函数。
client/method.js
implementation = function(args){
// define your client simulation / stub
};
server/method.js
implementation = function(args){
// define your server implementation
};
答案 1 :(得分:1)
了解如何构建应用:http://docs.meteor.com/#/full/structuringyourapp
如果您希望仅在服务器上运行方法,请将包含方法的文件放入server
文件夹。
如果您需要latency compensation,可以在方法中使用条件:
Meteor.methods({
method1: function() {
if (Meteor.isClient) {
//Do client side stuff
}
if (Meteor.isServer) {
//Do server side stuff
}
}
});