我有一个Books
和Chapters
集合。不言自明:一本书可以有很多章节。
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
。我做错了什么?
答案 0 :(得分:1)
TL / DR - 跳至3,因为它可能最相关,但我已将剩下的完整性包括在内。
我假设您将console.log...
行放在"click .delete-current-chapter"
回调中? currentChapter
变量将是该函数的本地变量,因此您无法通过在控制台中输入任何内容来获取任何内容。如果这很明显,请道歉,但不清楚你是不是从问题中做到这一点。
即使在回调中,currentChapter
也将成为游标,而不是文档或文档数组。使用findOne
返回单个doc(或null),或find(query).fetch()
返回一个数组(在这种情况下应该只是一个doc)。
您在何时何地尝试订阅singleChapter
?如果它在回调中,你必须记住,这不是一个反应函数。这意味着您将订阅(一旦您知道要订阅的_id
),但在收集实际准备好之前立即返回currentChapter
(因此没有任何内容)它)。在这种情况下,一旦集合准备就绪,回调就会重新运行,因为事件处理程序不被反应。
解决此问题的最简单方法是在订阅时使用onReady
callback,并在其中设置currentChapter
。另一种选择是在事件处理程序中自动停止Tracker.autorun
,但这似乎有点矫枉过正。
最后一点,您需要对使用此类设置的订阅保持谨慎,因为您可以轻松地为每个客户端累积数十个和几十个订阅,而Iron Router提供的自动订阅都不会停止。鉴于此用例,一旦您的回调运行并且相关项目已被删除,最好停止订阅。
答案 1 :(得分:1)
您的发布功能是否有效?也许Mongo有一个我不知道的功能,但我希望你需要包含{_id:id}
,而不仅仅是(id)。
Meteor.publish('singleChapter', function(id){
return Chapters.find({_id: id});
});