为什么即使我已经订阅了集合(Meteor),文档也会返回null?

时间:2014-12-10 17:12:05

标签: javascript meteor

我有一个BooksChapters集合。不言自明:一本书可以有很多章节。

subscriptions.js:

Meteor.publish("singleChapter", function(id) {
  return Chapters.find(id);
});

book_page.js:

Template.bookPage.helpers({
  chapters: function() {
    Chapters.find({
      bookId: this._id
    }, {
      sort: {
        position: 1
      }
    });
  }
});

book_page.html:

<template name="bookPage">
  <div class="chapter-list hidden">
    <div class="chapter-items">
    {{#each chapters}}
      {{> chapterItem}}
    {{/each}}
    </div>
  </div>
</template>

chapter_item.html:

<template name="chapterItem">
  <div class="chapter clearfix">
    <div class="chapter-arrows">
      <a class="delete-current-chapter" href="javascript:;">X</a>
    </div>
  </div>
</template>

现在,我正在尝试获取chapter_item.js中的当前章节项目:

Meteor.subscribe("singleChapter", this._id); // even tried this but didn't work

Template.chapterItem.events({
  "click .delete-current-chapter": function(e) {
    e.preventDefault();

    var currentChapter = Chapters.find(this._id);
  }
});

但是当我做的时候

console.log(currentChapter);

我得到undefined。我做错了什么?

2 个答案:

答案 0 :(得分:1)

TL / DR - 跳至3,因为它可能最相关,但我已将剩下的完整性包括在内。

  1. 我假设您将console.log...行放在"click .delete-current-chapter"回调中? currentChapter变量将是该函数的本地变量,因此您无法通过在控制台中输入任何内容来获取任何内容。如果这很明显,请道歉,但不清楚你是不是从问题中做到这一点。

  2. 即使在回调中,currentChapter也将成为游标,而不是文档或文档数组。使用findOne返回单个doc(或null),或find(query).fetch()返回一个数组(在这种情况下应该只是一个doc)。

  3. 您在何时何地尝试订阅singleChapter?如果它在回调中,你必须记住,这不是一个反应函数。这意味着您将订阅(一旦您知道要订阅的_id),但在收集实际准备好之前立即返回currentChapter(因此没有任何内容)它)。在这种情况下,一旦集合准备就绪,回调就会重新运行,因为事件处理程序不被反应。

    解决此问题的最简单方法是在订阅时使用onReady callback,并在其中设置currentChapter。另一种选择是在事件处理程序中自动停止Tracker.autorun,但这似乎有点矫枉过正。

  4. 最后一点,您需要对使用此类设置的订阅保持谨慎,因为您可以轻松地为每个客户端累积数十个和几十个订阅,而Iron Router提供的自动订阅都不会停止。鉴于此用例,一旦您的回调运行并且相关项目已被删除,最好停止订阅。

答案 1 :(得分:1)

您的发布功能是否有效?也许Mongo有一个我不知道的功能,但我希望你需要包含{_id:id},而不仅仅是(id)。

Meteor.publish('singleChapter', function(id){ return Chapters.find({_id: id}); });