Есть ли способ узнать, когда подписка на метеор «действительна»?

Если я изменю Session var и вызову повторную подписку через autosubscribe, есть ли какой-либо механизм обратного вызова, чтобы дождаться, пока «последние» данные не будут отправлены с сервера? [1]

Если вы посмотрите на эту суть, вы увидите некоторый код, который регистрирует содержимое коллекции с течением времени. по мере изменения подписки. Соответствующий раздел вывода:

at Subscribed; comments are: first post on #1 - second post on #1 
at Flushed; comments are: first post on #1 - second post on #1 
at Subscription complete; comments are: first post on #1 - second post on #1 - first post on #2 - second post on #2

Таким образом, даже после (а) вызова .subscribe, (б) вызова Meteor.flush (в) внутри обратного вызова onReady для .subscribe; в коллекции все еще есть устаревшие данные, и только в 3-м случае там есть «правильные» данные.

Я понимаю, что реактивные шаблоны и .observe в конечном итоге получат правильные данные, и все «установится» в правильное состояние. Но можем ли мы каким-то образом сказать, что мы еще не там?

Например, большинство приложений-примеров метеора (и моих собственных приложений) склонны к небольшим рывкам (аналогично FOUC) при добавлении и удалении данных из подписной коллекции. Если бы мы могли сказать, что подписка «загружается», мы могли бы что-то с этим сделать.

[1] Очевидно, что данные на сервере постоянно меняются, но, как вы увидите по сути, я не могу (без тайм-аута) найти точку, где это хотя бы правильно. Таким образом, мое использование «действительного» в вопросе.

Очень простой и распространенный вариант использования

Возьмите приложение madewith; когда вы впервые загружаете его, кажется, что приложений не зарегистрировано, пока данные не передаются по проводу, и приложения внезапно не появляются.

Причина этого в том, что Meteor.subscribe был вызван, но данные еще не поступили по сети. Но у шаблона нет простого способа сообщить, что данные ожидают обработки и что он должен показывать «загружающийся» шаблон. В madewith они действительно что-то делают, когда данные загружены, но это обратный вызов, и, таким образом, он выходит за рамки обычного метеоритного способа ведения дел (т. е. реактивного кодирования).

Было бы гораздо лучше (ИМО) написать что-то вроде:

 {{unless apps_loaded}}{{> loading}}{{/unless}}

а также

 Template.madewith.apps_loaded = function() { return !Apps.isComplete(); }

person Tom Coleman    schedule 29.05.2012    source источник


Ответы (2)


Интересный вопрос.

Правильное место для уведомлений о новых подписках — обратный вызов onReady. Обратите внимание, что ведение журнала всегда включает ваши новые данные. Проверка в пунктах (a) и (b) бесполезна, поскольку существует задержка между вызовом subscribe и получением всех данных с сервера.

Основная проблема заключается в том, что нет эквивалентного обратного вызова onRemove, который запускается после удаления данных для только что остановленной подписки. Более того, autosubscribe преднамеренно запускает новые сабвуферы перед остановкой старых, чтобы избежать мерцания.

Каков реальный вариант использования? В большинстве случаев такой обратный вызов не нужен, потому что шаблоны также могут ограничивать свои запросы данными, которые должны быть в области действия. В вашем примере помощник шаблона, который отображает комментарии, может запрашивать только комментарии с текущим post_id в сеансе, поэтому дополнительные комментарии в базе данных не повредят. Что-то вроде этого:

Template.post.comments = function () {
  return Comments.find({post_id: Session.get('post_id')});
};

Это позволяет применять более сложные стратегии, чем стандартная функция autosubscribe, например подписку на комментарии к трем последним сообщениям, просмотренным пользователем. Или подписаться на первые несколько комментариев для каждого сообщения, а затем отдельно подписаться на полный набор комментариев к сообщению, только когда это сообщение выбрано.

person debergalis    schedule 30.05.2012
comment
Хорошо, добавил вариант использования к вопросу. Я понимаю смысл области видимости, и это хорошо; Я предполагаю, что теперь вопрос заключается в том, есть ли (или у нас есть?) функция isComplete() в коллекции. - person Tom Coleman; 30.05.2012
comment
Разбивка на страницы - это реальный вариант использования - я разместил на нем новый вопрос. Я не вижу, как реализовать нумерацию страниц без мерцания, учитывая текущее состояние Метеора. - person Taylor Gautier; 07.10.2012

Я немного опоздал на метеоритную вечеринку, поэтому я не знаю истории, когда были добавлены метеорные функции, но просто для полноты теперь можно сделать это, используя подписки на уровне шаблона и 'subscriptionsReady' :

[js]
Template.myTemplate.onCreated(function() {
  this.subscribe('myData');
});

[html]
<template name="myTemplate">
  <h2>my Template</h2>
  {{#if Template.subscriptionsReady}}
    // code to loop/display myData
  {{else}}
    <p>Please wait..</p>
  {{/if}}
</template>
person Andy Lorenz    schedule 18.07.2015