Meteor наблюдает за изменениями, добавленными обратным вызовом на серверные огни по всему элементу

Tracker.autorun(function() {
  DATA.find().observeChanges({
    added: function(id, doc) {
       console.log(doc);
    }
  });
});

Этот код вызывается на сервере. Каждый раз, когда запускается метеоритный сервер, функция added запускается для каждого отдельного элемента в базе данных. Есть ли способ получить обратный вызов added только при добавлении новых элементов?

Ответы

Ответ 1

added будет вызываться для каждого документа в результирующем наборе при первом запуске observeChanges. Хитрость заключается в том, чтобы игнорировать обратный вызов в течение этого периода инициализации. У меня есть расширенный пример в ответе на этот вопрос, но этот код должен сработать для вас:

(function() {
  var initializing = true;
  DATA.find().observeChanges({
    added: function(id, doc) {
      if (!initializing) {
        console.log(doc);
      }
    }
  });
  initializing = false;
})();

Обратите внимание, что Tracker.autorun - это функция только для клиентов. На сервере я думаю, что он когда-либо выполняется один раз.

Ответ 2

Я боролся с этим в течение долгого времени. По какой-то причине ответ Дэвида не работал у меня - он стрелял после того, как переменная инициализации была установлена ​​в false.

Этот шаблон из Avi был успешным для меня:

var usersLoaded = false;
Meteor.subscribe("profiles", function () {
    // at this point all new users sent down are legitimately new ones
    usersLoaded = true;
});

Meteor.users.find().observe({
    added: function(user) {
        if (usersLoaded) {
            console.log("New user created: ", user);
        }
    }
});

Ответ 3

Поскольку это проблема с инициализацией, вы можете это сделать.

var observerOfMessages = Messages.find({}).observe({
    added: function(doc){
        if(!observerOfMessages) return;
        console.log(doc)
    }
});

Это более элегантно.

Ответ 4

Предоставить селектор запроса, который не соответствует старым элементам. Если вы используете mongo ObjectID как _id, вы можете запросить элементы, у которых _id больше, чем у последнего элемента:

const latest = DATA.findOne({}, {sort: {_id: -1}})
DATA.find({_id: {$gt: latest._id}}).observeChanges({
  added: function() { ... }
})

Или с createdAt меткой времени:

const currentTime = new Date()
DATA.find({createdAt: {$gt: currentTime}}).observeChanges({
  added: function() { ... }
})

Ответ 5

Вот еще один способ решить эту проблему:

Meteor.subscribe('messages', function() {
    var messages = Messages.find();
    var msgCount = messages.count();

    messages.observe({
        addedAt: function(doc, atIndex) {
            if(atIndex > (msgCount - 1)) console.log('added');
        }
    });
});

Должен срабатывать только для документов, добавленных после доставки существующей суммы. Важно, чтобы это выполнялось в обратном вызове onReady для Meteor.subscribe, так что msgCount изменяется по мере того, как ваша подписка... если, например, вы разбиваете страницы на подписки.

cursor.observe() документация