流星服务器反应性

问题描述:

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

I have an app with two collections

Books = new Meteor.Collection("books");
Chapters = new Meteor.Collection("chapters");

文档看起来很像这样:

Book = {
  _id : BookId,
  users_who_can_view_this_book : [userId, userId]
}

Chapter = {
  book : BookId
}

在服务器上,我像这样出版书籍和章节:

On the server I publish books and chapters like this:

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

在客户端我只是这样订阅:

On the client I just subscribe like this:

Meteor.subscribe('books');
Meteor.subscribe('chapters')

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

So, if a user has access to a book I want the client to receive the book and its corresponding chapters. This works fine on initial load.

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

Now, on the server I want to be able to add or remove users to/from the list on the book documents and when I do that, update the client with the new chapters. As of now, the client only get the update on the books, but the chapters referring to that book is not added/removed from the client.

我知道我需要改变章节出版的工作方式.我已经查看了 cursor.observe 和 cursor.observeChange 的文档,但我真的无法掌握在这种情况下如何使用它们.我也研究过这个答案,但我不要得到它的全部.我很乐意解释我对该答案的哪些部分有疑问,但由于情况略有不同,我不知道是否相关.无论如何,我们将不胜感激!

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!

完全未经测试、无保证的代码,但将您的 Meteor.publish('chapters') 函数替换为:

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.

我刚刚写了这个,但至少它应该引导你朝着正确的方向使用observeChanges()来解决你的问题.

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.

同样,正如 mquandalle 所说,如果您将 Chapters 文档放在 Book 文档中可能会更好.根据您当前的设置,如果您的章节集合开始变得非常庞大,您的服务器性能将受到重大影响.

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.

希望有帮助!