我正在尝试将文档插入到彼此相关的集合中:Posts
,Comments
和Categories
。 Comments
和Categories
中的每个文档都必须包含PostId
字段。
我创建了一个名为insertSamplePost
的方法,该方法应该在将文档插入Posts
后返回帖子的ID。我已将此方法调用分配给变量,如下所示:
var postId = Meteor.call('insertSamplePost', samplePost, function(error, id) {
if (error) {
console.log(error);
} else {
return id;
}
});
但是,当我稍后尝试使用postId插入相关的注释和类别时,它似乎未定义!有谁知道发生了什么?
这是我的完整代码:
if (Meteor.isClient) {
Template.post.events({
'click .new-sample-post' : function (e) {
var samplePost = {
title: "This is a title",
description: "This is a description"
};
// Insert image stub
var postId = Meteor.call('insertSamplePost', samplePost, function(error, id) {
if (error) {
console.log(error);
} else {
return id;
}
});
// This returned undefined. :-()
console.log(postId);
var sampleComment = {
body: "This is a comment",
postId: postId
};
var sampleCategory = {
tag: "Sample Category",
postId: postId
};
Comments.insert(sampleComment);
Categories.insert(sampleCategory);
}
});
}
// Collections
Posts = new Meteor.Collection('posts');
Comments = new Meteor.Collection('comments');
Categories = new Meteor.Collection('categories');
// Methods
Meteor.methods({
insertSamplePost: function(postAttributes) {
var post = _.extend(postAttributes, {
userId: "John Doe",
submitted: new Date().getTime()
});
return Posts.insert(post);
}
});
答案 0 :(得分:1)
当你这样做时:
var myVar = Meteor.call("methodName", methodArg, function(error, result) {
return result;
}
您的myVar
变量实际上是Meteor.call()
返回的内容,而不是您的回调函数返回的内容。相反,你可以做的是:
var postId;
Meteor.call('insertSamplePost', samplePost, function(error, id) {
if (error) {
console.log(error);
} else {
postId = id;
}
});
但是,正如Akshat所提到的那样,当回调函数实际运行并异步设置postId
时,对其他集合的insert
调用将已经运行。
如果您完全避免使用服务器方法,这段代码实际上会更简单一些 - 您可以修改集合allow
回调中的文档:
Template.post.events({
'click .new-sample-post' : function (e) {
var samplePost = {
title: "This is a title",
description: "This is a description"
};
var postId = Posts.insert(samplePost);
var sampleComment = {
body: "This is a comment",
postId: postId
};
var sampleCategory = {
tag: "Sample Category",
postId: postId
};
Comments.insert(sampleComment);
Categories.insert(sampleCategory);
}
});
现在,您可以在userId
回调中添加submitted
和Posts.allow()
字段:
Posts.allow({
insert: function(userId, doc) {
doc.userId = userId;
doc.submitted = new Date().getTime();
return true;
}
});
如果您愿意,您仍然可以在第一个insert
的回调中执行两个辅助insert
,以使操作更具原子性(换句话说,确保辅助操作)如果第一个insert
失败,则insert
不会发生。
答案 1 :(得分:0)
您可以使用Session
来存储结果,因为Session
是被动的,而客户端javascript是异步的,因此您无法使用return
直接将结果分配给变量。
所以你得到未定义的原因是因为Meteor.call的结果是在回调中给出的。回调将在稍后产生结果,并且当它返回结果时,其余代码将已经运行。这就是使用Session的好主意,因为您可以在模板助手中使用它。
然而,为了插入帖子,最好只在回调中插入注释和类别,因为你没有在html中显示结果。
Meteor.call('insertSamplePost', samplePost, function(error, postId) {
if (error) {
console.log(error);
} else {
var sampleComment = {
body: "This is a comment",
postId: postId
};
var sampleCategory = {
tag: "Sample Category",
postId: postId
};
Comments.insert(sampleComment);
Categories.insert(sampleCategory);
}
});
这样,如果结果是错误,则不会插入注释和类别。