javascript - Meteor "counts-by-room"导致模板无法加载的示例

标签 javascript meteor publish subscribe

我使用 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/

相关文章:

javascript - 线性插值在经典柏林噪声中如何工作?

javascript - JSF:强制页面重新加载时,从托管 Bean 调用 javascript 代码不起作用

javascript - 在 http 请愿后选择 angularjs 不更新标题

javascript - javascript 中的预期标识符或字符串

deployment - 使用生产标志缩小的 meteor 无法加载某些文件

javascript - 如何使用相同的表格使用 quickForm 更新/插入记录?

javascript - meteor :迭代嵌套元素

html - 发布到 rpubs 现有的 html 文件

entity-framework - 如何将解决方案发布到 Azure

android - 应用已在 Android Market 中发布,但在某些手机中不可见