【问题标题】:Issue with subscriptions on multiple instances of a template模板的多个实例上的订阅问题
【发布时间】:2016-01-23 02:52:32
【问题描述】:

这里是场景。我有一个包含#each 循环并呈现特定模板实例的模板,根据文档在每个模板上设置数据上下文。

<template name = 'live'>
<div class = 'row'>
    {{#each runways}}
        <div class = 'col-md-2'>
            {{> runway_panel}}
        </div>
    {{/each}}
</div>

</template>

这是支持它的助手:

Template.live.helpers({
    runways: function(){
        return Runway_Data.find();
    }
});

这行得通,我的问题如下。每个 live_event_log 实例都有一个模板级订阅,该订阅订阅一个发布,该发布采用数据上下文的 _id 参数,如下所示:

Template.runway_panel.onCreated(function(){
    var instance = this;
    instance.autorun(function(){
        var subscription = instance.subscribe('runway_status', this.data._id);
    });

    instance.status = function(){
        return Runway_Status.find();
    }

});

这是出版物:

Meteor.publish('runway_status', function(runway){ 

    if(this.userId){
        //Retrieve the last know status for the given runway

        return Runway_Status.find({runway: runway});  
    }

});

这一切都崩溃了,我在浏览器控制台上得到了这个:

 [Log] Exception in queued task: http://localhost:3000/client/views/live/runway_panel.js?4efaac87b39527d3dfd3d65a174520f9bce3c565:4:73 (meteor.js, line 888)_withTemplateInstanceFunc@http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3476:16
http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1864:54
_withCurrentView@http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2197:16

一旦我注释掉订阅行,其他一切正常,我是否在这里遗漏了一些非常明显的东西?是否与多次订阅同一出版物有关?

谢谢! :)

解决方案

感谢 Jeremy S. 的投入和夜班后的一些睡眠,我终于在没有自动运行的情况下弄清楚了。所以这里是为了后代:

Template.runway_panel.onCreated(function(){
    var self = this;
    self.subscribe('runway_status', this.data._id);
});

应该先睡一会再试!

【问题讨论】:

  • 你能给我们原始的控制台错误吗?不是日志。您可能需要添加检查 if (this.data._id)
  • 我已经尝试过了,但我得到了同样的错误,data._id 肯定存在,因为如果我在订阅之前将它打印到日志中,它总是存在的。好像和烈焰有关系。我为我的无知道歉,但你原来的错误是什么意思?我发布的就是我在控制台上得到的所有内容(至少是其中的一部分,日志条目会永远存在)。

标签: javascript html meteor meteor-blaze


【解决方案1】:

问题在于您的订阅中的this.data._id,现在它的范围仅限于最里面的函数。你想要instance.data._id(它是非反应性的,所以你不需要autorun)或Template.currentData()(它是反应性的)。

Template.runway_panel.onCreated(function(){
    var instance = this;
    instance.autorun(function(){
        var data = Template.currentData();
        var subscription = instance.subscribe('runway_status', data._id);
    });
});

另请注意,在您的出版物中,如果 this.userIdundefined,则应将其标记为 this.ready()。但这不是错误的根源。

【讨论】:

  • 终于搞定了,谢谢!不过,你现在让我很感兴趣。你说 instance.data._id 是非反应性的。您将如何使用 instance.data._id 而不是自动运行来重写它?有几天同时渲染,我试图将开销保持在最低限度。谢谢!
  • 哦,没关系,想通了,记录在问题上。谢谢 Jeremy S.,非常感谢。
【解决方案2】:

首先,userId 是一个函数,userId() 将返回当前用户 ID。您可以查看here 以了解instance.subscribe 的更多详细信息。

我认为在Meteor.publish 中获取runway._id 时可能会出现您的问题

Template.runway_panel.onCreated(function(){
  var instance = this;
  // instance subscribe data whose _id is runwayPanelId
  instance.autorun(function(){
    var dataContext = Template.currentData();
    var subscription = instance.subscribe('runway_status', dataContext.runwayPanelId);
  });

  instance.status = function(){
    return Runway_Status.find();
  }
});

// publication
Meteor.publish('runway_status', function(runway){ 
  // using Meteor.userId() to get current user id
  if(Meteor.userId()){
      //Retrieve the last know status for the given runway
      return Runway_Status.find({runway: runway});  
    }
});

<template name = 'live'>
  <div class = 'row'>
    {{#each runways}}
      <div class = 'col-md-2'>
        {{> runway_panel runwayPanelId=_id}}
      </div>
    {{/each}}
  </div>

</template>

【讨论】:

  • 我的印象是 Meteor.userId() 在任何地方都可用,但发布功能:/ 无论如何,我正在取得一些进展。我将采用与您在 dataContext 中建议的解决方案相同的解决方案。还在努力!谢谢
猜你喜欢
  • 2021-02-19
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
相关资源
最近更新 更多