Используйте проекцию для публикации метеора подписаться

У меня есть структура элемента пользовательского интерфейса, которая работает только с определенной моделью данных (ожидается объект с «текстовым» ключом). Это отличается от модели данных, которая существует в моем mongodb. Итак, моей первой идеей было использовать проекцию и опубликовать ее для слушателей.

var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db; db.Element.aggregate({$project: { _id:1, text:"$description"}});

Проблема в том, что это не курсор, а просто объект ejson. Какую стратегию я должен использовать, чтобы предоставить инфраструктуре пользовательского интерфейса необходимые данные и иметь привязку реактивности/данных с обеих сторон.


person Sonne    schedule 26.01.2016    source источник
comment
В качестве быстрого обходного пути я использую Meteor.map и _.extend, чтобы добавить дополнительное поле к курсору, но на самом деле это не реактивно.   -  person Sonne    schedule 26.01.2016
comment
для этого есть несколько пакетов, таких как reywood:publish-composite или peerlibrary:reactive-publish   -  person MrE    schedule 26.01.2016


Ответы (1)


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

Например, когда вы возвращаете курсор из публикации, Meteor вызывает функцию _publishCursor, которая выглядит так:

Mongo.Collection._publishCursor = function (cursor, sub, collection) {
  var observeHandle = cursor.observeChanges({
    added: function (id, fields) {
      sub.added(collection, id, fields);
    },
    changed: function (id, fields) {
      sub.changed(collection, id, fields);
    },
    removed: function (id) {
      sub.removed(collection, id);
    }
  });

  // We don't call sub.ready() here: it gets called in livedata_server, after
  // possibly calling _publishCursor on multiple returned cursors.

  // register stop callback (expects lambda w/ no args).
  sub.onStop(function () {observeHandle.stop();});

  // return the observeHandle in case it needs to be stopped early
  return observeHandle;
};

Таким образом, вы можете изменить свою публикацию, чтобы в основном делать то же самое, но также опубликовать текстовое поле, которое получает свое значение из поля описания, например:

Учитывая следующую коллекцию:

MyCollection = new Mongo.Collection("my_collection");

Ваша функция публикации может выглядеть так:

Meteor.publish("myPub", function () {
  var sub = this;
  var observeHandle = myCollection.find().observeChanges({
    added: function (id, fields) {
      fields.text = fields.description;  // assign text value here   
      sub.added("my_collection", id, fields);
    },
    changed: function (id, fields) {
      fields.text = fields.description;  // assign text value here 
      sub.changed("my_collection", id, fields);
    },
    removed: function (id) {
      sub.removed("my_collection", id);
    }
  });

  sub.ready()

  // register stop callback (expects lambda w/ no args).
  sub.onStop(function () {observeHandle.stop();});

};
person bluebird    schedule 27.01.2016