我无法通过Meteor.call调用Accounts.findUserByEmail()服务器端

时间:2016-12-07 20:09:08

标签: javascript meteor

我只是想验证一个帐户是否存在特定的电子邮件,但我了解到Accounts.findUserByEmail()仅适用于服务器端。

似乎反复建议的方法是定义Meteor.method()并在那里完成所有工作。不幸的是,我显然不知道我在做什么,因为我收到了一个其他人没有得到的错误。

component.js:

Meteor.call('confirm', email);

methods.js:

Meteor.methods({
  'confirm': (email) => {
    if (Accounts.findUserByEmail(email)) {
      return;
    }
  }
});

我得到的只是这个错误:

Exception while simulating the effect of invoking 'confirm' TypeError: Accounts.findUserByEmail is not a function

我是否完全误解了Meteor.methods + Meteor.call的动态?它实际上不是服务器端吗?

目前正在使用Meteor包,accounts-password@1.3.3

2 个答案:

答案 0 :(得分:3)

Meteor通过运行方法的“存根”来模拟前端的方法调用。我们的想法是获得更好的用户体验,因为UI会在服务器响应之前立即更新。但是,这也意味着如果在Meteor方法中运行仅服务器代码,则必须确保代码仅在服务器上运行:

Meteor.methods({
  'confirm': (email) => {
    if (Meteor.isServer && Accounts.findUserByEmail(email)) {
      return;
    }
  }
});

或者,您可以将上述方法定义放在仅加载到服务器上的文件中,例如/server目录中的任何文件或/imports中的{推荐)文件只有include d服务器代码。然后,您不需要单独使用Meteor.isServer

答案 1 :(得分:2)

如果您的客户端代码包含方法定义,则将其视为存根,这意味着它以特殊模式运行,该模式提供"乐观UI"一旦实际的服务器方法将其响应返回给客户端,它就会撤消对数据的影响。

为客户端和服务器实现(至少某些)方法的不同版本并避免在客户端上包含其中一些方法可能是值得的。

如果您选择在客户端和服务器上使用相同的功能,则Meteor.isServerMeteor.isClientthis.isSimulation(后者专门用于方法)允许您只能在客户端/服务器上执行某些块。

请注意,问题中的代码不符合您的预期,并且您不会检查方法参数。

对于这个特定用例,您可能应该只在服务器上实现该方法(只是不在客户端版本中导入其代码):

Meteor.methods({
  isEmailInSystem(email) {
    check(email, String);
    return !!Accounts.findUserByEmail(email);
  }
});

您可以在The Meteor Guide中了解有关方法生命周期的更多信息。

从指南(要点,省略一些细节):

  
      
  1. 方法模拟在客户端上运行 - 如果我们在客户端和服务器代码中定义此方法,就像所有方法一样,则在调用它的客户端中执行方法模拟。 / p>      

    客户端进入一种特殊模式,它跟踪对客户端集合所做的所有更改,以便以后可以回滚它们。完成此步骤后,应用程序的用户会立即使用客户端数据库的新内容查看其UI更新,但服务器尚未收到任何数据。

  2.   
  3. 方法DDP消息将发送到服务器
  4.   
  5. 方法在服务器上运行
  6.   
  7. 将返回值发送给客户
  8.   
  9. 受此方法影响的所有DDP出版物均已更新
  10.   
  11. updated邮件发送到客户端,数据替换为服务器结果,方法回调触发
      在将相关数据更新发送到正确的客户端之后,服务器将在方法生命周期中发回最后一条消息 - 带有相关方法ID的DDP更新消息。客户端回滚在步骤1中的方法模拟中对客户端数据所做的任何更改,并将其替换为在步骤5中从服务器发送的实际更改。

         

    最后,传递给Meteor.call的回调实际上是用第4步的返回值触发的。重要的是回调等到客户端是最新的,这样你的Method回调可以假设客户端状态反映了任何变化在方法内完成。

  12.