【问题标题】:Is there a post createUser hook in meteor when using accounts-ui package?使用 accounts-ui 包时,meteor 中是否有 post createUser 挂钩?
【发布时间】:2016-01-08 17:05:13
【问题描述】:

假设我有一个待办事项应用程序,我想确保每个注册的用户至少有一个待办事项开始,例如“第一个要划掉的待办事项!”,我将如何在流星中做到这一点?

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

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

我想我一定遗漏了一些简单的东西,如果这非常明显,请道歉。任何帮助表示赞赏。

【问题讨论】:

    标签: meteor


    【解决方案1】:

    Meteor API 现在有钩子onCreateUser

    Accounts.onCreateUser(function (options, user) {
      Todos.insert({
        owner: user._id,
        text: "First todo to cross off!",
      });
    
      // We still want the default hook's 'profile' behavior.
      if (options.profile)
        user.profile = options.profile;
    
      return user;
    });
    

    【讨论】:

    • 这个函数实际上是一个PRE Create User钩子,我想大多数人想要的,实际上OP是你在创建用户之后执行一些东西。
    • @DanailGabenski 它适用于 OP 的目的。我已经更新了我的答案来展示它。
    • @Danail:确实,_id 包含在用户对象中。希望这个PR gets accepted 让文档提及这一点。
    • @DanDascalescu 不确定这是否是最近的行为,即未创建用户帐户或 _id 不可用。将不得不尝试使用最新版本,但接受该 PR 是个好主意。
    • 适合作为帖子帐户创建挂钩,因为创建可能仍会失败,例如当电子邮件地址已存在时。
    【解决方案2】:

    我使用了上面描述的 _.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);
    });
    

    【讨论】:

    【解决方案3】:

    如果您使用的是UserAccounts 包:postSignUpHook 现在存在。

    Splendido 刚刚合并了我针对这个问题的拉取请求。

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

    Documentation(你需要向下滚动它是最后一个钩子):

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

    【讨论】:

    【解决方案4】:

    您可以通过包装它们来搭载 Meteor 调用的函数。我还使用了accounts-ui 和accounts-password 包,并使用Underscore 的_.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,它可能看起来像这样(也在客户端代码中的某处):

    Accounts.createUser = _.wrap(Accounts.createUser, function(createUser) {
    
      // Store the original arguments
      var args = _.toArray(arguments).slice(1),
          user = args[0],
          origCallback = args[1];
    
      // Create a new callback function
      // Could also be defined elsewhere outside of this wrapped function
      // This is called on the client
      var newCallback = function(err) {
        if (err) {
          console.error(err);
        } else {
          console.info('success');
        }
      };
    
      // Now call the original create user function with
      // the original user object plus the new callback
      createUser(user, newCallback);
    
    });
    

    希望对您有所帮助。

    【讨论】:

      【解决方案5】:

      Meteor 开发者之一在 Meteor google 小组中回答了这个问题:https://groups.google.com/forum/?fromgroups=#!topic/meteor-talk/KSz7O-tt4w8

      基本上,现在,在使用 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 反应方法来设置登录挂钩来检查 Meteor.userId() 中的更改。只有当用户登录/重新加载页面时才会调用它。这对于非收藏内容更有用,因为在设置 Meteor.userId 时不能保证加载收藏:

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

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

      【讨论】:

      • 这已被David's answer 废弃。
      • @DanDascalescu 实际上不是,因为大卫的回答没有提供解决方案来挂钩“用户创建并登录”
      【解决方案6】:

      我认为这个问题更好地回答了这个问题:How can I create users server side in Meteor?

      在简历中:

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

      查看流星文档了解更多信息:http://docs.meteor.com/#/full/accounts_createuser

      【讨论】:

      • OP 特别提到“还有一种方法可以使用带有回调的 Accounts.createNewUser 以编程方式创建用户,但我使用的是 accounts-ui 包,所以我没有以编程方式添加用户。”跨度>
      猜你喜欢
      • 2014-08-25
      • 1970-01-01
      • 2013-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      • 1970-01-01
      相关资源
      最近更新 更多