我有一个包含两个馆藏的应用
Books = new Meteor.Collection("books");
Chapters = new Meteor.Collection("chapters");
文档看起来非常像这样:
Book = {
_id : BookId,
users_who_can_view_this_book : [userId, userId]
}
Chapter = {
book : BookId
}
在服务器上,我发布了这样的书籍和章节:
Meteor.publish('books', function() {
return Books.find({ users_who_can_view_this_book : { $in : [this.userId] } });
});
Meteor.publish('chapters', function() {
var bookIds = Books.find({
users_who_can_view_this_book : {$in : [this.userId] }
}).map(function(book) {
return book._id;
});
return chapters.find({book: {$in : bookIds}});
});
在客户端我只是这样订阅:
Meteor.subscribe('books');
Meteor.subscribe('chapters')
因此,如果用户有权访问某本书,我希望客户端能够收到该书及其相应的章节。这在初始加载时工作正常。
现在,在服务器上,我希望能够在书籍文档的列表中添加或删除用户,当我这样做时,请使用新章节更新客户端。截至目前,客户端仅获取书籍的更新,但不会从客户端添加/删除引用该书的章节。
我知道我需要改变我的章节出版物的工作方式。我查看了cursor.observe和cursor.observeChange的文档,但在这种情况下我真的无法掌握如何使用它们。我也研究过this answer,但我没有得到所有这些。我很乐意解释我对这个答案的哪些部分有疑问,但由于这是一个稍微不同的案例我不知道是否相关。无论如何,对此或一个工作实例的一些指导将非常感激!
答案 0 :(得分:2)
完全未经测试,无保证代码,但用以下内容替换您的Meteor.publish('章节')功能:
Meteor.publish('chapters-for-me', function() {
var self = this;
var handle = Books.find({users_who_can_view_this_book : {$in : [self.userId] }}).observeChanges({
added: function(id) {
Chapters.find({book: id}).forEach(function(chapter) {
self.added("chapters", chapter._id, chapter);
});
},
removed: function(id) {
Chapters.find({book: id}).forEach(function(chapter) {
self.removed("chapters", chapter._id);
});
}
});
self.ready();
self.onStop(function () {
handle.stop();
});
});
...然后将您的订阅更改为:
Meteor.subscribe('books');
Meteor.subscribe('chapters-for-me');
...并保留您的收藏声明。
我只是动态地写了这篇文章,但至少它应该指导你如何使用observeChanges()来解决你的问题。
再次,正如mquandalle所说,如果你将章节文件放在书籍文件中可能会更好。使用当前的设置,如果您的Chapters集合开始变得非常大,那么您的服务器性能将会受到重创。
希望有所帮助!