1

我有一个包含两个集合的应用程序

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')

因此,如果用户可以访问一本书,我希望客户收到这本书及其相应的章节。这在初始加载时工作正常。

现在,在服务器上,我希望能够在书籍文档的列表中添加或删除用户,当我这样做时,用新章节更新客户端。截至目前,客户端仅获得书籍的更新,但引用该书籍的章节并未从客户端添加/删除。

I understand that I need to change the way my chapters publication work. I have looked at the docs for cursor.observe and cursor.observeChange, but I really cannot grasp how to use them in this case. I have also studied this answer but I dont get all of it. I'd be happy to explain what parts of that answer I have questions about but since it's a slightly different case I dont know if is relevant. Anyway, some guidance on this or a working example would be much appreciated!

4

1 回答 1

2

Totally untested, no-guarantees code, but replace your Meteor.publish('chapters') function with this:

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();
  });

});

...and then change your subscriptions to this:

Meteor.subscribe('books');
Meteor.subscribe('chapters-for-me');

... and leave your collection declarations as they are.

I just wrote this on the fly, but at the very least it should steer you in the right direction on how to use observeChanges() to solve your problem.

Again, as mquandalle stated, it would probably be better if you put your Chapters documents inside your Book documents. With your current setup, if your Chapters collection starts to get really big, your server performance is going to take a significant hit.

Hope that helps!

于 2013-03-30T16:55:39.850 回答