假设我有一个todo应用程序,我想确保每个注册的用户都至少有一个todo开始,类似“第一次交叉!”,我将如何在流星中做到这一点?
一般来说,我看到它的方式,我可以在第一次创建用户(理想)时执行此操作,或者每次登录时检查是否需要新的待办事项(不太理想)。在后一种情况下,我可以检查Todos.findOne()
,如果计数为0,则添加一个。但是,似乎无论我是在页面加载时在路由器中执行此操作,还是在某个模板的.rendered
函数上,我正在检查的集合尚未加载,因此我总是创建一个新的待办事项,即使一个确实存在。如果有人可以解释如何解决这个问题,那就太棒了。
但是,我理想的是能够在创建用户时创建新的Todo。有Accounts.onCreateUser
方法,但用于向用户个人资料添加其他信息,而不是后创建挂钩。还有一种方法可以使用带有回调的Accounts.createNewUser
以编程方式创建用户,但我使用的是accounts-ui包,因此我没有以编程方式添加用户。在一个不太理想的情况下,我可以在用户登录时检查Todo,但即使在这种情况下,似乎还有联合Accounts.loginWithXService
登录,因此在任何用户登录时都不确定如何处理回调,无论服务类型如何。
我认为我必须遗漏一些简单的事情,如果这是非常明显的,那么道歉。任何帮助表示赞赏。
答案 0 :(得分:18)
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;
});
答案 1 :(得分:10)
我使用了上面描述的_.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);
});
答案 2 :(得分:10)
postSignUpHook
现已存在。Splendido刚刚将我的拉取请求合并到了这个问题上。
AccountsTemplates.configure({
/*...*/
postSignUpHook: /*[callback with your actions post full user creation goes here]*/,
/*...*/
}
Documentation(你需要向下滚动它是最后一个钩子):
func(userId,info)仅在服务器端调用,在成功创建用户帐户之后,提交pwdForm进行注册:允许在我们确定新用户成功后对提交的数据执行自定义操作创建。常见用途可能是将角色应用于用户,因为这只有在完成用户创建后才能实现:角色。 userId可用作第一个参数,因此可以检索用户对象。密码不可用,因为密码已经加密,但如果使用密码,可以在信息中找到加密密码。
答案 3 :(得分: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);
});
希望这有帮助。
答案 4 :(得分:2)
其中一个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'
所以我认为有效的解决方案仍然存在于某个地方,但是希望用我在此期间找到的解决方法更新这篇文章。
答案 5 :(得分:-3)
我认为这更好地回答了这个问题: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