Meteor:如何发布依赖于其他集合的游标的游标 [英] Meteor: How to publish cursor that is depending on cursor of other collection
问题描述
我的Meteor项目中有以下数据结构:
- 具有属于用户(作者)的一组list-id的用户
- 列出实际上包含列表的所有数据
I'm having the following data structure in my Meteor project:
- Users with a set of list-ids that belong to the user (author)
- Lists that actually contain all the data of the list
现在我正在尝试将用户的所有列表发布到客户端。这是一个简单的例子:
Now I'm trying to publish all Lists of a user to the client. Here is a simple example:
if (Meteor.isClient) {
Lists = new Meteor.Collection("lists");
Deps.autorun(function() {
Meteor.subscribe("lists");
});
Template.hello.greeting = function () {
return "Test";
};
Template.hello.events({
'click input' : function () {
if (typeof console !== 'undefined')
console.log(Lists.find());
}
});
}
if (Meteor.isServer) {
Lists = new Meteor.Collection("lists");
Meteor.startup(function () {
if ( Meteor.users.find().count() === 0 ) {
Accounts.createUser({ //create new user
username: 'test',
email: 'test@test.com',
password: 'test'
});
//add list to Lists and id of the list to user
var user = Meteor.users.findOne({'emails.address' : 'test@test.com', username : 'test'});
var listid = new Meteor.Collection.ObjectID().valueOf();
Meteor.users.update(user._id, {$addToSet : {lists : listid}});
Lists.insert({_id : listid, data : 'content'});
}
});
Meteor.publish("lists", function(){
var UserListIdsCursor = Meteor.users.find({_id: this.userId}, {limit: 1}).lists;
if(UserListIdsCursor!=undefined){
var UserListIds = UserListIdsCursor.fetch();
return Lists.find({_id : { $in : UserListIds}});
}
});
Meteor.publish("mylists", function(){
return Meteor.users.find({_id: this.userId}, {limit: 1}).lists;
});
//at the moment everything is allowed
Lists.allow({
insert : function(userID)
{
return true;
},
update : function(userID)
{
return true;
},
remove : function(userID)
{
return true;
}
});
}
但是发布列表不能正常工作。任何想法如何解决这一问题?我也发布了mylists以保证用户可以访问list字段。
But publishing the Lists doesn't work properly. Any ideas how to fix this? I'm also publishing "mylists" to guarantee that the user has access to the field "lists".
推荐答案
解决方案
Solution
Lists = new Meteor.Collection('lists');
if (Meteor.isClient) {
Tracker.autorun(function() {
if (Meteor.userId()) {
Meteor.subscribe('lists');
Meteor.subscribe('myLists');
}
});
}
if (Meteor.isServer) {
Meteor.startup(function() {
if (Meteor.users.find().count() === 0) {
var user = {
username: 'test',
email: 'test@test.com',
password: 'test'
};
var userId = Accounts.createUser(user);
var listId = Lists.insert({data: 'content'});
Meteor.users.update(userId, {
$addToSet: {lists: listId}
});
}
});
Meteor.publish('lists', function() {
check(this.userId, String);
var lists = Meteor.users.findOne(this.userId).lists;
return Lists.find({_id: {$in: lists}});
});
Meteor.publish('myLists', function() {
check(this.userId, String);
return Meteor.users.find(this.userId, {fields: {lists: 1}});
});
}
更改
Changes
- 在客户端和服务器之外声明
列表
集合(无需声明两次)。 - 订阅时确保用户已登录。 (性能增强)。
- 插入测试用户时,请使用所有插入函数返回id(减少代码)的事实。
- 确保用户在发布时登录。
- 简化
列出
发布功能。 - 已修复
myLists
发布功能。发布需要返回游标,游标数组或虚假值。你不能返回一个id数组(这个代码无法访问,因为你需要做一个fetch
或一个findOne
)。重要说明 - 这将发布另一个具有列表
字段的用户文档。在客户端上,它将与现有用户文档合并,因此只有登录用户才会有列表
。如果您希望所有用户在客户端上都有该字段,那么我建议您只将其添加到用户个人资料中。
- Declare the
Lists
collection outside of the client and server (no need to declare it twice). - Ensure the user is logged in when subscribing. (performance enhancement).
- When inserting the test user, use the fact that all insert functions return an id (reduces code).
- Ensure the user is logged in when publishing.
- Simplified
lists
publish function. - Fixed
myLists
publish function. A publish needs to return a cursor, an array of cursors, or a falsy value. You can't return an array of ids (which this code doesn't access anyway because you need to do afetch
or afindOne
). Important note - this publishes another user document which has thelists
field. On the client it will be merged with the existing user document, so only the logged in user will havelists
. If you want all users to have the field on the client then I'd recommend just adding it to the user profiles.
警告:在编写本文时,如果附加了其他列表项,则不会发布它们,因为列表
发布功能只会在用户登录时重新运行。为了使其正常工作,你需要一个被动加入。
Caution: As this is written, if additional list items are appended they will not be published because the lists
publish function will only be rerun when the user logs in. To make this work properly, you will need a reactive join.
这篇关于Meteor:如何发布依赖于其他集合的游标的游标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!