使用accounts ui包时meteor中是否有post createUser挂钩?
假设我有一个todo应用程序,我想确保每个注册的用户都至少有一个todo开始,比如“第一个要删除的todo!”,我该如何在meteor中这样做 一般来说,在我看来,我可以在用户第一次创建时执行(理想),或者在每次登录时检查他们是否需要新的todo(不太理想)。在后一种情况下,我可以检查使用accounts ui包时meteor中是否有post createUser挂钩?,meteor,Meteor,假设我有一个todo应用程序,我想确保每个注册的用户都至少有一个todo开始,比如“第一个要删除的todo!”,我该如何在meteor中这样做 一般来说,在我看来,我可以在用户第一次创建时执行(理想),或者在每次登录时检查他们是否需要新的todo(不太理想)。在后一种情况下,我可以检查Todos.findOne(),如果计数为0,则添加一个。然而,似乎无论我在加载页面时在路由器中还是在某个模板的.rendered函数中执行此操作,我正在检查的集合尚未加载,因此我总是创建一个新的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()
- 您可以使用
reactive方法设置登录挂钩,以检查Meteor.userId()中的更改。只有当用户登录/重新加载页面时,才会调用该函数。这对于非集合内容更有用,因为设置Meteor.userId时不保证加载集合:Meteor.autorun
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]*/,
/*...*/
}