使用accounts ui包时meteor中是否有post createUser挂钩?

使用accounts ui包时meteor中是否有post createUser挂钩?,meteor,Meteor,假设我有一个todo应用程序,我想确保每个注册的用户都至少有一个todo开始,比如“第一个要删除的todo!”,我该如何在meteor中这样做 一般来说,在我看来,我可以在用户第一次创建时执行(理想),或者在每次登录时检查他们是否需要新的todo(不太理想)。在后一种情况下,我可以检查Todos.findOne(),如果计数为0,则添加一个。然而,似乎无论我在加载页面时在路由器中还是在某个模板的.rendered函数中执行此操作,我正在检查的集合尚未加载,因此我总是创建一个新的todo,即使确实

假设我有一个todo应用程序,我想确保每个注册的用户都至少有一个todo开始,比如“第一个要删除的todo!”,我该如何在meteor中这样做

一般来说,在我看来,我可以在用户第一次创建时执行(理想),或者在每次登录时检查他们是否需要新的todo(不太理想)。在后一种情况下,我可以检查
Todos.findOne()
,如果计数为0,则添加一个。然而,似乎无论我在加载页面时在路由器中还是在某个模板的
.rendered
函数中执行此操作,我正在检查的集合尚未加载,因此我总是创建一个新的todo,即使确实存在。所以,如果有人能解释一下如何避开这个问题,那就太好了

但是,在理想情况下,我希望能够在创建用户时创建一个新的Todo。有一个
Accounts.onCreateUser
方法,但用于向用户配置文件中添加附加信息,而不是创建后挂钩。还有一种方法可以使用带有回调的
Accounts.createNewUser
以编程方式创建用户,但我使用的是Accounts ui包,因此我不会以编程方式添加用户。在一个不太理想的情况下,每当用户登录时,我都可以检查Todo,但即使在这种情况下,似乎也有一个联合的
Accounts.loginWithXService
login,因此无论服务类型如何,都不确定当任何用户登录时如何处理回调


我想我一定错过了一些简单的东西,所以如果这是非常明显的,我道歉。感谢您的帮助。

Meteor开发者之一在Meteor google group中回答了这个问题:

基本上,现在使用accounts ui时没有createUser钩子,只有通过
accounts.createUser
以编程方式这样做时才有。此外,没有用于登录的钩子,除非使用较低级别的登录功能,如
loginWithFacebook
,等等。我还没有找到一个理想的方法来解决这个问题,但有几种方法可以处理它:

  • 如果需要在集合中输入默认值,请在该集合的订阅中使用onComplete参数。在此回调中,如果集合中没有条目,请添加一个条目。这避免了我在帖子中提到的第一个问题,即不知道何时加载集合,但这并不理想,因为集合可能为空,因为用户已经删除了第一个默认集合:

    Meteor.subscribe 'todos', user: Meteor.userId(), () ->
      todo = Todos.findOne()
      unless todo
        Todos.insert user: Meteor.userId()
    
  • 您可以使用
    Meteor.autorun
    reactive方法设置登录挂钩,以检查Meteor.userId()中的更改。只有当用户登录/重新加载页面时,才会调用该函数。这对于非集合内容更有用,因为设置Meteor.userId时不保证加载集合:

    Meteor.autorun () ->
      if Meteor.userId()
        console.log 'Do some post login hook'
    

因此,我认为有效的解决方案仍然存在,但我想用我在此期间找到的解决方法更新这篇文章。

你可以通过包装Meteor调用的函数来实现。我还使用accounts ui和accounts password软件包,并使用下划线的u.wrap方法重新定义loginWithPassword函数。默认情况下,Meteor中包含下划线

我使用类似这样的方式登录:

Meteor.loginWithPassword = _.wrap(Meteor.loginWithPassword, function(login) {

  // Store the original arguments
  var args = _.toArray(arguments).slice(1),
      user = args[0],
      pass = args[1],
      origCallback = args[2];

  // Create a new callback function
  // Could also be defined elsewhere outside of this wrapped function
  var newCallback = function() { console.info('logged in'); }

  // Now call the original login function with
  // the original user, pass plus the new callback
  login(user, pass, newCallback);

});
在这种特定的情况下,上面的代码将放在您的客户机代码中的某个地方

对于Accounts.createUser,它可能看起来像这样(也在客户端代码中的某个地方):


希望这会有所帮助。

我使用了上面描述的u.wrap方法,但希望包含一个额外的建议。从新的自定义回调调用原始回调是个好主意。Meteor在回拨中做了一些我们不想错过的事情

修改后的代码对我来说就像冠军一样:

Accounts.createUser = _.wrap(Accounts.createUser, function(createUser) {

    // Store the original arguments
    var args = _.toArray(arguments).slice(1),
        user = args[0];
        origCallback = args[1];

    var newCallback = function(error) {
        // do my stuff

        origCallback.call(this, error);
    };

    createUser(user, newCallback);
});

Meteor API现在有一个钩子:


我认为这更好地回答了这个问题:

在简历中:

 Accounts.createUser({
                        username: username,
                        email : email,
                        password : password,
                        profile  : {
                            //publicly visible fields like firstname goes here
                        }

});
查看meteor文档了解更多信息:

如果您使用的是包:
postSignUpHook
现在已经存在。 Splendido刚刚合并了我对这个问题的请求

AccountsTemplates.configure({
    /*...*/
    postSignUpHook: /*[callback with your actions post full user creation goes here]*/,
    /*...*/
}
(您需要向下滚动,这是最后一个钩子):

调用func(userId,info),仅在服务器端,在成功创建用户帐户之后,提交pwdForm以进行注册:允许在我们确定成功创建新用户后对提交的数据执行自定义操作。一个常见的用途可能是将角色应用于用户,因为这只有在alanning:roles中完全完成用户创建后才可能实现。userId作为第一个参数可用,因此可以检索用户对象。密码不可用,因为它已加密,但如果需要,可以在信息中找到加密密码


这个函数实际上是一个预创建的用户钩子,我认为大多数人想要的,实际上是OP,是在用户被创建之后执行一些东西。@DanailGabenski它可以很好地用于OP的目的。我已经更新了我的答案来演示它。@Danail:事实上,
\u id
包含在用户对象中。希望文档能提到这一点。@DanDascalescu直到最近还不确定这是不是一种行为,即用户帐户未创建或_id不可用。必须使用最新版本进行尝试,但最好接受该PR。这不适合作为post帐户创建挂钩,因为创建可能仍然失败,例如当电子邮件地址已经存在时。OP特别提到“还有一种方法可以使用Accounts.createNewUser和回调以编程方式创建用户,但我使用的是Accounts ui包,所以我不会以编程方式添加用户。”这一点已被淘汰。@DanDascalescu事实上并非如此,因为David的回答没有提供“用户创建并登录”的解决方案“对于其他用例,重要的是要记住,这在服务器端不起作用@portforwardpodcast等,
crea
 Accounts.createUser({
                        username: username,
                        email : email,
                        password : password,
                        profile  : {
                            //publicly visible fields like firstname goes here
                        }

});
AccountsTemplates.configure({
    /*...*/
    postSignUpHook: /*[callback with your actions post full user creation goes here]*/,
    /*...*/
}