Meteor.publish: публикация коллекции, которая зависит от другой коллекции
У меня есть функция публикации следующим образом:
Meteor.publish('tasks', function (name) {
var project = Projects.findOne({name: name});
return Tasks.find({projectId: project._id});
});
Предположим, что в какой-то момент в проекты были внесены изменения, в результате вышеприведенный Projects.findOne
возвращает другой проект, и Tasks.find вернет другие задачи.
Однако изменения, внесенные в проекты, не переиздают задачи
Я использовал replivePublish, но выясняется, что у пакета есть проблемы (а также нет модульных тестов). Итак, есть ли простой способ сделать эту функцию публикации повторно опубликованной при изменении проекта?
Ответы
Ответ 1
Обзор
На момент написания статьи реактивные объединения являются нерешенной проблемой. Полный обзор см. В Реактивные соединения в Метеор.
Рекомендации
Я сильно рекомендую напрямую использовать observChanges. Это невероятно трудно понять, и легко развить утечку памяти. Если вы мне не верите, посмотрите это видео на EventedMind. Это заставит ваши глаза кровоточить.
В этой проблеме есть несколько пакетных решений. метеоритный гид рекомендует publish-composite.
Если вы считаете, что использование пакетного решения неприемлемо, внимательно ознакомьтесь с разделом "Присоединение к клиенту" от "Реактивные соединения в Метеор" . Он чист, но требует больше времени ожидания части пользователя. Также см. Мой пост в шаблон объединяется, если вы предпочитаете активировать подписки на уровне шаблона.
Ответ 2
Теперь на блоке появился новый ребенок. Полное серверное решение для реактивного опубликования. (Отказ от ответственности: я один из авторов.) Он разработан так, что вы можете использовать его как обычно, как и следовало ожидать с помощью autorun
. Он автоматически заботится обо всем.
Установите пакет, вызвав meteor add peerlibrary:reactive-publish
.
С добавленным пакетом вы можете просто сделать:
Meteor.publish('tasks', function (name) {
this.autorun(function (computation) {
var project = Projects.findOne({name: name}, {fields: {_id: 1}});
return Tasks.find({projectId: project._id});
});
});
Точно так же, как и следовало ожидать.: -)
Важной частью является ограничение полей в первом запросе только на _id
, в противном случае autorun
будет повторяться каждый раз при изменении любого поля документа проекта. Вы этого не хотите.