2017-02-23 102 views
0

the docs是否有必要停止订阅与流星的帮佣级订阅?

如果调用Meteor.subscribe反应的计算中,例如使用Tracker.autorun,当计算无效或停止订阅将自动取消;

然后明确提到,不需要在autorun内停止订阅。

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

EDIT

下面是代码表示的情况的一个片段。 接下来的问题是:我需要做些什么来阻止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({}); 
}, 
}); 
+0

你为什么订阅帮手?这对我来说似乎很奇怪。你能显示你的代码吗? – zim

+0

我已经添加了一小段代码。我在帮助程序中订阅的原因是让数据上下文可用,我将能够在订阅参数 – EugVal

+0

中使用好,我明白你在做什么。我有一个想法,我会把答案。 – zim

回答

1

我不喜欢做一些有助益的事情,比如去服务器。一个帮助程序可以在模板处于活动状态时多次调用,所以imho应该只会返回一个值。

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

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(),则应用相同的概念:数据返回后,您可以检查它并订阅从集合需要的内容。

1

好问题!

你是正确的,一个模板帮手实际上是一个反应计算。因此,根据文档,应该遵循的是,您不必停止由帮助者开始的订阅。但是你知道当你认为会发生什么......

所以我决定测试一下,以确保它在实际中是真的。根据我的测试,您的问题的答案是您不必停止由帮手启动的订阅。

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

<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个订阅。

1

您可以使用此chrome extension来查看流星订阅和取消订阅的时间。 @ jordanwillis指出,您可能会看到它从帮手中的订阅中取消订阅。此外,我建议这server transform package做一个订阅,而不是在一个帮手。

+0

这确实是Chrome的一个有用的扩展。 – zim