2017-02-23 36 views
0

По the docs:Нужно ли останавливать подписку на подписку на уровне помощника с помощью Meteor?

Если вы звоните 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) не будет реактивной. (в публикации вы можете установить слушателей на добавленные и измененные события и добавить дополнительные поля к опубликованным объектам, т. е. данные из объектовSub).

Если объекты должны быть реактивными, тогда я, вероятно, обработаю подписку в 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({}); 
}, 
}); 

в этом 2-й пример, может быть, что это немного странно, это я использую находку() вместо этого findOne() вы» re, чтобы получить доступ к слушателям таким образом. поэтому, возможно, вам нужно будет проверить способ публикации или фильтрации на клиенте.

Если вы хотите придерживаться метода findOne(), то применяется такая же концепция: как только данные будут возвращены, вы можете изучить его и подписаться на то, что вам нужно для рабской коллекции.

1

Хороший вопрос!

Вы правы, что помощник Template на самом деле является реактивным вычислением. Следовательно, в документах следует следовать за тем, что вам не нужно останавливать подписку, начатую помощником. Но вы знаете, что происходит, когда вы предполагаете ...

Итак, я решил проверить это, чтобы убедиться, что это действительно так на практике. На основании моего теста ответ на ваш вопрос: вам не нужно останавливать подписку, которая была запущена помощником.

Если вам интересно, вот мой тестовый код (обратите внимание, что я использовал коллекцию в своем приложении, содержащую список активных пользователей).

<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

Это действительно полезное расширение для хрома. – zim

 Смежные вопросы

  • Нет связанных вопросов^_^