我使用 Meteor 文档中的“按房间计数”示例来计算项目中某个“条目”的“评论”数量。现在,当我点击某个条目时,模板未加载。它需要刷新。我是否把这个例子弄乱了?这是我的代码。我不太明白其中的“初始化”部分,也不知道该怎么做才能让它正常工作。
服务器:
Meteor.publish("counts-by-entry", function (entryId) {
var self = this;
check(entryId, String);
var count = 0;
var initializing = true;
var handle = Reviews.find({entry: entryId}).observeChanges({
added: function (id) {
count++;
if (!initializing)
self.changed("counts", entryId, {count: count});
},
removed: function (id) {
count--;
self.changed("counts", entryId, {count: count});
}
});
initializing = false;
self.added("counts", entryId, {count: count});
self.ready();
self.onStop(function () {
handle.stop();
});
});
客户端(铁路由器):
this.route('entry', {
path: '/entry/:_id',
layoutTemplate: 'layout',
yieldTemplates: {
'navigation': {to: 'navigation'},
'pt_entry': {to: 'content'}
},
waitOn: function () {
Meteor.subscribe('singleEntry', this.params._id),
Meteor.subscribe('entryReviews', this.params._id),
Meteor.subscribe('counts-by-entry', this.params._id);
},
data: {
singleEntry: function () {return Entries.findOne()},
reviews: function () {return Reviews.find({entry: Session.get('entryId')}, {sort: {date: -1}})},
count: function () {return Counts.findOne(Session.get("entryId")).count + " reviews."}
},
before: function() {
Session.set("activeNav", Router.current().route.name),
Session.set("entryId", this.params._id);
},
notFoundTemplate: 'notFoundTemplate'
});
还有:
Counts = new Meteor.Collection("counts");
最佳答案
我只是尝试重新创建您的示例所需的最小数量以使其正常工作,但我没有遇到与您相同的问题。
您的浏览器中是否打开了 JavaScript 控制台?我会在那里寻找错误,通常当收集数据对客户端不可用时调用助手时会发生这种情况。这就是您所使用的iron-router 的waitOn 修复的内容。
在我的复制品中,我只有一个订阅(按条目计数),因此其他订阅可能存在问题。
至于初始化部分的作用:
发布 block 是将为每个客户端订阅运行的一段代码。它做了两件事,它为客户端提供数据的初始有效负载,在传统出版物中,该数据负载将是集合查询中的所有文档,然后它对影响查询结果的更改使用react,并将这些更改发送给客户端。
以下是您将看到的最常见的出版物:
Meteor.publish("all-reviews", function() {
return Reviews.find({});
});
Meteor 隐藏了本出版物中实际发生的事情的复杂性。这更接近实际情况:
Meteor.publish("all-reviews", function() {
var self = this;
//this is the query we want realtime updates for
//when relevant additions, removals or changes happen the correct callbacks will fire...
var handle = Reviews.find({}).observeChanges({
added: function(id, fields) {
//when a document is added it gets sent to the client.
//Note: the initial payload of data happens here, lets say you had 5 reviews
//this would get called 5 times as soon as a user subscribes.
self.added("reviews", id, fields);
},
removed: function(id) {
//when a document is removed the client is told which one
self.removed("reviews", id);
},
changed: function(id, fields) {
//when a document has a change made to its fields the changes get sent
self.changed("reviews", id, fields);
}
});
//letting the client know that the initial payload of data has been sent.
//Stuff like iron-routers waitOn would rely on this message before loading a template
//that relies on this publication
self.ready();
//stops the publication running forever. This will fire when a client no longer needs a
//subscription or when they close the page.
self.onStop(function() {
handle.stop();
});
});
至于文档示例中使用初始化标志发生的情况。初始化标志用于简单地计算您案例中现有评论的所有初始有效负载,然后在observeChanges调用之后告诉客户端有多少。这是对另一种方法的优化,另一种方法是在初始负载期间向客户端发送几条 self.changed 消息。
如果我展示如何在没有标志的情况下完成它,也许会更有意义:
Meteor.publish("counts-by-entry", function (entryId) {
var self = this;
check(entryId, String);
var count = 0;
//we need to initially add the document we are going to increment
self.added("counts", entryId, {count: 0});
var handle = Reviews.find({entry: entryId}).observeChanges({
added: function (id) {
count++;
//So for example if there were 100 reviews for this entry when the user
//subscribes this self.changed would get called 100 times:
//self.changed("counts", entryId, {count: 1})
//self.changed("counts", entryId, {count: 2})
//self.changed("counts", entryId, {count: 3})
//self.changed("counts", entryId, {count: 4}) etc...
//which is a waste when we can just initially tell the client how
//many reviews there are at the point of them subscribing
self.changed("counts", entryId, {count: count});
},
removed: function (id) {
count--;
self.changed("counts", entryId, {count: count});
}
});
//remove the self.added(...) which handles the optimiation as explained above
self.ready();
self.onStop(function () {
handle.stop();
});
});
无论如何,看起来问题并不是那个特定的发布。我希望控制台能够明确问题所在
关于javascript - Meteor "counts-by-room"导致模板无法加载的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23592514/