我在Meteor中遇到订阅/发布问题。我编写了一个示例Meteor应用程序来帮助缩小问题的范围。
我在服务器上发布一个集合,该集合由通过客户端订阅传入的参数过滤。此订阅位于autosubscribe中,该自动订阅利用会话变量来反应性地更新订阅。
更改此特定会话变量的状态时,客户端上的集合未正确更新,或者至少是我收集的内容。我花了整整一天的时间在我控制的代码中没有发现问题。我怀疑我要么不理解如何在Meteor中设置正确的pub-sub,要么Meteor中存在问题。
要重现此问题,请启动一个新的Meteor项目并使用以下内容(确保在尝试时删除autopublish包):
HTML(例如test.html):
<head>
<title>pubsubbug</title>
</head>
<body>
{{> main}}
</body>
<template name="main">
<h1>Example showing possible bug in Meteor wrt pub-sub</h1>
<p><button name="showall">show all ({{showall}})</button></p>
<div style="float:left;width:400px;">
<h2>Notes:</h2>
<ul>
{{#each notes}}
<li>{{title}}</li>
{{/each}}
</ul>
</div>
<div style="float:left;">
<h2>Notes (copied):</h2>
<ul>
{{#each notes_copied}}
<li>{{title}}</li>
{{/each}}
</ul>
</div>
</template>
JS(例如test.js)
if (Meteor.is_client) {
Notes = new Meteor.Collection("notes_collection");
NotesCopied = new Meteor.Collection("notes_collection_copied");
Session.set("showall", false);
Meteor.autosubscribe(function () {
Meteor.subscribe("notes_subscription", Session.get("showall"), function () {
console.log("Notes count:", Notes.find().count());
});
Meteor.subscribe("notes_subscription_copied", Session.get("showall"), function () {
console.log("Bug? This isn't getting called.");
console.log("NotesCopied count:", NotesCopied.find().count());
});
});
Template.main.notes = function () {
return Notes.find();
};
Template.main.notes_copied = function () {
return NotesCopied.find();
};
Template.main.showall = function () {
return Session.get("showall");
};
Template.main.events = {
"click button[name='showall']": function (evt) {
Session.set("showall", !Session.get("showall"));
}
};
}
if (Meteor.is_server) {
Notes = new Meteor.Collection("notes_collection");
var getNotes = function (showall) {
if (showall) {
return Notes.find({}, {sort: {title: 1}});
} else {
return Notes.find({visible: true}, {sort: {title: 1}});
}
};
Meteor.publish("notes_subscription", function (showall) {
// By sending the Notes back with the same uuid as before, the
// client end seems to get confused:
return getNotes(showall);
});
Meteor.publish("notes_subscription_copied", function (showall) {
var notes = getNotes(showall);
var self = this;
// Copy notes into a new notes collection (see NotesCopied on client).
// By generating a new uuid, we don't get an issue with the notes
// on the client getting screwed up:
notes.forEach(function (note) {
var uuid = Meteor.uuid(); // note._id will cause same problem
self.set("notes_collection_copied", uuid, {title: note.title});
});
self.flush();
self.complete();
});
// Add example notes
Meteor.startup(function () {
if (Notes.find().count() === 0) {
Notes.insert({title: "Note #1 (always visible)", visible: true});
Notes.insert({title: "Note #2 (always visible)", visible: true});
Notes.insert({title: "Note #3 (always visible)", visible: true});
Notes.insert({title: "Note #4 (only visible when showall true)", visible: false});
Notes.insert({title: "Note #5 (only visible when showall true)", visible: false});
Notes.insert({title: "Note #6 (only visible when showall true)", visible: false});
}
});
}
您将看到的内容的解释:
单击时会有一个按钮,只需在true和false之间切换会话变量(showall)。
存在两个订阅(在自动订阅中),一个用于举例说明错误,另一个用_copied
作为后缀,这是一个测试,用于证明当有问题的集合被“复制”并且新的uuid是分配后,结果显示正确。我无法弄清楚如何处理这些特殊的信息...我不想要新的uuid。
所以基本上,当重复点击显示所有按钮时,第一列 Notes:将显示不正确的结果,点击几下后就不会显示任何内容。
另一方面,第二列 Notes(复制):,每次都重新生成uuid,显示正确。
这是一个错误吗?或者有正确的方法来做到这一点吗?
编辑:上面的示例活在http://pubsubbug.meteor.com/
答案 0 :(得分:2)
没有在Windows上的开发人员分支上遇到您的错误。既然如此,那么您的代码没有任何问题是一个好兆头。您可能会看到有关订阅和/或Mongo如何查询的错误消息。
Meteor本身最有可能在其托管上运行稳定(= master)版本,因此您必须尝试不同的方法或等待新版本。除非你能支持在devel上运行......