【问题标题】:Is it necessary to stop subscribing in helper level subscriptions with Meteor?是否有必要停止使用 Meteor 订阅助手级别的订阅?
【发布时间】:2017-07-13 09:07:19
【问题描述】:

根据the docs

如果您在响应式计算中调用 Meteor.subscribe,例如使用 Tracker.autorun,则订阅将在计算无效或停止时自动取消;

然后明确提到没有必要在autorun 中停止订阅。

流星助手也是这样吗?我相信他们算作reactive computation,但我不完全确定!

编辑

这是一个代表这种情况的sn-p代码。 那么问题来了:我需要做些什么来停止objectsSub 还是全部自动排序?

<template name ="Foo">
 {{#with myContext}}
    {{#each objects}}
     <!--Show stuff-->
    {{/each}}
 {{/with}}
</template>

Template.Foo.onCreated(function(){
  this.subscribe('myContextSub');
});

Template.foo.helpers({
 myContext(){
    return MyContextCollection.findOne();
 },
 objects(){
    Meteor.Subscribe('objectsSub',this.someContextAttribute);
    return ObjectsCollection.find({});
 },
});

【问题讨论】:

  • 你为什么要订阅助手?这对我来说似乎很奇怪。你能展示你的代码吗?
  • 我在代码中添加了一个小sn-p。我在帮助程序中订阅的原因是有可用的数据上下文,我将能够在订阅参数中使用
  • 好的,我明白你在做什么。我有几个想法,我会回答。

标签: meteor publish-subscribe meteor-blaze


【解决方案1】:

您可以使用此chrome extension 查看流星何时订阅和取消订阅。正如@jordanwillis 指出的那样,您可能会在帮助程序中看到它取消订阅。我还推荐这个 server transform package 在一个订阅中而不是在助手中做所有事情。

【讨论】:

  • 这确实是一个有用的 chrome 扩展。
【解决方案2】:

好问题!

您是正确的,模板助手实际上是一种反应式计算。因此,根据文档,您不必停止由助手启动的订阅。但是你知道当你假设时会发生什么......

所以我决定对此进行测试,以确保它在实践中是真的。根据我的测试,您的问题的答案是您不必停止由助手启动的订阅

如果您好奇,这里是我的测试代码(注意我在我的应用中使用了一个包含活跃用户列表的集合)。

<template name='main_template'>
  <p>Number of Active Users: {{numUsers}}</p>

  {{#if isNotDestroyed}}
    <p>Number of Active Users (from sub-template): {{> sub_template}}</p>
  {{/if}}

  <a href="#" class="js-destroy">Destroy sub-template</a>
</template>

<template name='sub_template'>
  {{numUsers}}
</template>


Template.main_template.onCreated(function() {
  this.destory = new ReactiveVar(false);
});

Template.main_template.helpers({
  numUsers: function() {
    return ActiveUsers.find().count();
  },

  isNotDestroyed: function() {
    return !Template.instance().destory.get();
  }
});

Template.main_template.events({
  'click .js-destroy'(template, instance) {
    console.log('setting destory');
    instance.destory.set(true);
  },
});

Template.sub_template.onCreated(function() {
  console.log("I was created!");
});

Template.sub_template.onDestroyed(function() {
  console.log("I was destroyed!");
});

Template.sub_template.helpers({
  numUsers: function() {
    Meteor.subscribe('activeUsers');
    return ActiveUsers.find().count();
  },
});

如您所见,我订阅了子模板中的集合,但我正在计算主模板和子模板中的记录数。在初始运行时,两个计数都返回相同的值。但是,当我“销毁”子模板(通过使用 ReactiveVar 实现)时,主模板中的计数变为 0。这意味着订阅已停止,本地集合已被清除。

最后一点,我完全同意@zim 的建议。除了他的建议外,您还可以使用Meteor Publish Composite 包在仅 1 个订阅中处理此问题。

【讨论】:

    【解决方案3】:

    我不喜欢在助手中做任何有副作用的事情,比如去服务器。在模板处于活动状态时,助手可以被多次调用,所以恕我直言,它实际上应该只返回一个值。

    在您的情况下,至少我会将订阅绑定到模板,因此当模板被销毁时订阅就会消失。例如

    Template.foo.helpers({
     objects() {
        Template.instance().subscribe('objectsSub',this.someContextAttribute);
        return ObjectsCollection.find({});
     },
    });
    

    更有可能的是,当主集合 (myContextSub) 发布时,我会在服务器端处理这个“加入”。但这仅是在从属集合(objectsSub)预计不会反应的情况下。 (在发布中,您可以在添加和更改的事件上设置监听器,并为发布的对象添加额外的字段,即来自 objectsSub 的数据)。

    如果 objectsSub 将是响应式的,那么我可能会在模板的 onCreated() 中处理订阅。在客户端上,您将在主集合上设置一个添加的侦听器,然后在主集合中的项目发布时订阅相关的从属集合。然后助手可以像现在一样简单地执行 find() 。例如

    Template.foo.onCreated(function() {
        let self = this;
    
        self.subscribe('myContextSub');
    
        let cursor = MyContextCollection.find();
    
        cursor.observe({
            added: function(newDocument) {
                // loop through the objects on newDocument, pulling out the context attributes to subscribe one or more times...
                self.subscribe('objectsSub', someContextAttribute[s]);
            },
            changed: function(newDocument, oldDocument) {
                // same as added
            }
        });
    });
    

    现在从属助手可以更简单了:

    Template.Foo.helpers({
     myContext() {
        return MyContextCollection.findOne();
     },
     objects() {
        return ObjectsCollection.find({});
     },
    });
    

    在第二个示例中,可能有点奇怪的是我使用的是 find() 而不是您正在使用的 findOne(),以便以这种方式访问​​侦听器。所以也许您需要检查它在客户端上的发布或过滤方式。

    如果你想坚持使用 findOne(),同样的概念也适用:一旦数据返回,你可以检查它并订阅你需要的从属集合。

    【讨论】:

      猜你喜欢
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 2019-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-10
      相关资源
      最近更新 更多