Как получить актуальную коллекцию по подписке onReady (ранее onComplete)

У меня возникла проблема с обратным вызовом onReady на Meteor.subscribe. Когда он вызывается, в документации указано: Подписка отмечена как завершенная. Однако коллекция, которую он модифицирует, может не обрабатывать различия между последней подпиской.

Быструю демонстрацию можно увидеть, изменив пример Todos:

$ meteor create --example todos

Отредактируйте client/todos.js, см. строку 34. Замените блок автоподписки на:

Meteor.autosubscribe(function () {
  var list_id = Session.get('list_id');
  var onReady = function (done) {
    var list, todos = Todos.find();
    if (todos) {
      list = todos.map(function (todo) {
        return todo.text;
      });
      if (done) {
        console.log("subscription onReady called again 100ms later:", list);
      } else {
        console.log("subscription onReady called:", list);
        setTimeout(function () {
          onReady(true);
        }, 100);
      }
    }
  };
  if (list_id)
    Meteor.subscribe('todos', list_id, onReady);
});

Запустите пример и щелкните от одного Todo List к другому (см. вверху слева), наблюдая за консолью. Вы заметите, что при вызове onReady коллекция содержит оба документа из предыдущего списка задач, объединенных с недавно выбранным списком задач.

На самом деле это не ошибка, потому что onReady никогда не подразумевал, что он будет запущен, когда коллекция будет обновлена, а только после завершения подписки. .

Любые предложения, чтобы подойти к этому? Есть ли способ получать уведомления сразу после обновления коллекции после подписки? Интересно, должен ли я полагаться на .observe... но на клиента? Это доступно на стороне клиента? Я могу попробовать это завтра... но я хотел бы услышать решения

К вашему сведению: мой вариант использования вращается вокруг плагина typeahead Bootstrap JS. Я запускаю подписку с поисковым запросом на сервер. Сервер публикует результаты поиска, и как только клиент получает эти данные (надеялся, что onReady будет правильным выбором...), я приступаю к заполнению/обновлению источника ввода.


person matb33    schedule 06.08.2012    source источник
comment
Мне удалось заставить это работать, действительно используя наблюдение на стороне клиента. Вскоре я опубликую код, чтобы продемонстрировать, как это будет сделано.   -  person matb33    schedule 06.08.2012
comment
После сна и восстановления ясной головы мне пришло в голову, что автоподписка делает именно то, что мне нужно. Теперь это кажется таким очевидным...   -  person matb33    schedule 08.08.2012


Ответы (1)


Я задал подобный вопрос здесь: есть ли способ узнать, когда подписка на метеор "действительна"?

Короче говоря, вы правы в том, что происходит; ответ заключается в том, чтобы правильно отфильтровать коллекцию Todos при ее использовании:

Template.foo.todos = function() { 
  return Todos.find({list_id: Session.get('list_id')});
}
person Tom Coleman    schedule 06.08.2012