2012-06-11 3 views
21

Предположим, я пишу:Получить коллекцию Метеор по имени

new Meteor.Collection("foos"); 
new Meteor.Collection("bars"); 

Есть ли API для доступа к этим коллекции по имени? Что-то вроде Meteor.Collection.get(name), где name is "foos" или "bars"? Я знаю, что я мог бы написать что-то вроде

var MyCollections = { 
    foos: new Meteor.Collection("foos"); 
    bars: new Meteor.Collection("bars"); 
} 

, а затем использовать MyCollections[name], но я бы предпочел, чтобы использовать существующий API, если таковой существует.

ответ

3

Насколько я могу видеть в источнике collection.js, в настоящее время в api нет способа получить существующую коллекцию по имени, как только она уже была инициализирована на сервере. Возможно, было бы не сложно добавить эту функцию.

Итак, почему бы не разветвить Метеор и не отправить патч или создать смарт-пакет и поделиться им. Я уверен, что есть другие, которые хотели бы иметь такую ​​же функцию.

+0

Принимая этот ответ, поскольку он основан на чтении [источника] (https://github.com/meteor/meteor/blob/master/packages/mongo-livedata/collection.js). –

+7

нашел его на 'Meteor.connection._mongo_livedata_collections' – nepjua

+0

@nepjua, который не является правильной коллекцией, попробуйте вставить его в консоль javascript, и вы увидите, что данные вставляются в клиенте, но не отправляются на сервер. – malhal

0

Вместо того, чтобы смотреть, я просто делал:

Foos = new Meteor.Collection("foos"); 

или, возможно, поместить его внутрь другого объекта. Я действительно не делал объект коллекции Collections.

+0

Правильно, я знаю, что смогу это сделать. Но у меня есть большое количество коллекций, которые используют один и тот же код, поэтому я хотел бы ссылаться на них по имени. –

0

Обратите внимание, что у них есть возвращаемое значение, так что вы можете просто сделать

var Patterns = new Meteor.Collection("patterns"); 

и использовать Patternsвезде.

И когда вам нужно подписаться на обновления сервера, предоставьте "patterns" до Meteor.subscribe().


Если у вас есть один и тот же код для нескольких коллекций, возможность высока, что вы делаете что-то неправильно с точки зрения разработки программного обеспечения; почему бы не использовать одну коллекцию с полем type (или что-то еще, что отличает документы) и использовать это вместо использования нескольких коллекций?

+1

Хорошо указать, что кажется очевидным упущением из OP, что вызов 'new Mongo.Collection' возвращает объект коллекции. С другой стороны, простое имя коллекции для 'Meteor.subscribe()' может не работать, если функция публикации использует другое имя. Подробнее см. [Общие сведения о публикации/подписке Meteor] (http://stackoverflow.com/a/21853298/1269037). –

-1
var bars = new Meteor.Collection("foos"); 

Судя по тому, что делает этот collection.js, линия используется для создания экземпляра объекта коллекции открывает соединение с базой данных и ищет коллекцию, совпадающую с именем мы даем. Таким образом, в этом случае происходит соединение, и коллекция «foos» привязана к «барам» объекта Meteor.Collection. См. collection.js И remote_collection_driver.js в пакете монго-жилая.

Как и в случае с MongoDB, в то время как вы можете, вам не нужно явно создавать коллекции. Как указано в документации MongoDB:

A collection is created when the first document is inserted.

Так что, я думаю, что вы после того, что у вас уже есть - если я не совсем понял, что вы намерения.

0

Кажется, что нет способа добраться до обернутого объекта Meteor.Collection, не сохраняя его во время создания, как упомянули другие.

Но есть, по крайней мере, способ перечислить все созданные коллекции и фактически получить доступ к соответствующему объекту Mongo LocalCollection.Они доступны из любого объекта Meteor Collection, поэтому, чтобы сохранить его универсальным, вы можете создать фиктивную коллекцию только для этого. Используйте метод как таковой (CoffeeScript):

dummy = new Meteor.Collection 'dummy' 
getCollection = (name) -> 
    dummy._driver.collections[name] 

Эти объекты имеют все находкой, findOne, обновлять и др методы, и даже те, которые, кажется, не Метеор разоблачить, как pauseObservers и resumeObservers, которые кажутся интересными , Но я не пробовал возиться с этой ссылкой Mongo LocalCollection напрямую, чтобы знать, что он соответствующим образом обновит коллекцию сервера.

+2

Примечание: .collection доступен только на клиенте, как часть LocalCollectionDriver (https://github.com/meteor/meteor/blob/master/packages/mongo-livedata/local_collection_driver.js). Таким образом, этот подход предоставит вам все коллекции, опубликованные клиентом, но не обязательно все коллекции в целом. – AlexeyMK

-2

У кого-нибудь есть решение для этого? Было бы здорово, чтобы быть в состоянии сделать это:

Handlebars.registerHelper('getCollection', function(e) { 
return Meteor.collection(e) // or something like this 
}); 

и имеют шаблонный код, как

{{#each getCollection 'myCollection' }} 

Это было бы очень полезно, как я заметил, что некоторые увольнения делают это ж/хелперов шаблона метеора. ..

-2

Вы всегда можете свернуть собственный автоматический сборщик.

Скажите, что у вас есть пара коллекций под названием «Бизнес» и «Клиенты». Поместите ссылку каждый в некоторый объект «коллекции» и зарегистрируйте помощник Handlebars для доступа к этим «коллекциям» по коллекциям [«name»]. не

т.е. поставить что-то вроде этого на стороне клиента main.js:

collections = collections || {}; 
collections.Businesses = Businesses; 
collections.Clients = Clients; 

Handlebars.registerHelper("getCollection", function(coll) { 
    return collections[coll].find(); 
}); 

Затем в HTML, просто обратитесь к сборнику по имени:

{{#each getCollection 'Businesses'}} 
    <div> Business: {{_id}} </div> 
{{/each}} 

{{#each getCollection 'Clients'}} 
    <div> Client: {{_id}} </div> 
{{/each}} 

Look мы, не более общий характер " список всех записей "требуется шаблонный js!

15

на основе mongoinspector Шейн Donelley в https://github.com/shanedonnelly1/mongoinspector

getCollection = function (string) { 
for (var globalObject in window) { 
    if (window[globalObject] instanceof Meteor.Collection) { 
     if (globalObject === string) { 
      return (window[globalObject]); 
      break; 
     };   
    } 
} 
return undefined; // if none of the collections match 
}; 
+2

Вы можете сделать то же самое на сервере, используя *** this *** вместо *** window ***. Код тот же, просто замените *** window *** на *** этим ***, чтобы получить объекты коллекции из глобального пространства имен. – Alberto

+2

Вне глобального контекста и в строгом режиме используйте 'var globals = Function ('return this')();', чтобы получить ссылку на объект Global. Поэтому замените *** window *** *** *** в коде кодом *** globals ***. – Alberto

+0

Этот шаблон используется [meteor-autocomplete] (https://github.com/mizzao/meteor-autocomplete/blob/master/autocomplete-server.coffee#L8). –

11

Я только что нашел этот пакет: https://github.com/dburles/mongo-collection-instances/

Это позволит вам

Foo1 = new Mongo.Collection('foo'); // local 
Foo2 = new Mongo.Collection('foo', { connection: connection }); 

Mongo.Collection.get('foo') // returns instance of Foo1 

Mongo.Collection.get('foo', { connection: connection }); 
// returns instance of Foo2 

Надежда это поможет

+2

Примечание. Этот пакет больше не нужен, потому что теперь получение существующих коллекций является встроенной функцией. – malhal

+0

@malhal У вас есть ссылка, которая показывает, как это сделать в текущей версии? – Jankapunkt

+0

@Jankapunkt sure http://stackoverflow.com/a/37938322/259521 – malhal

6

Эта функция была добавлена ​​к M eteor в феврале 2016 года: "Provide a way to access collections from stores on the client"

Это работает так:

Meteor.connection._stores['tasks']._getCollection();

И я использую его следующим образом, чтобы проверить вставки с помощью консоли JavaScript:

Meteor.connection._stores['tasks']._getCollection().insert({text:'test'});

Для вставьте его, чтобы пакет insecure был установлен, иначе был получен отказ в доступе.

+1

Можно ли назвать это с сервера и на стороне клиента? Я пробовал этот код и всегда получаю ** TypeError: Не могу прочитать свойство «_stores» неопределенного ** на стороне сервера. – grahan

1

С https://github.com/dburles/mongo-collection-instances вы можете использовать Mongo.Collection.get('collectionname')

Обратите внимание, что параметр вы вставляя это тот же, который вы используете при создании коллекции. Поэтому, если вы используете const Products = new Mongo.Collection('products'), тогда вы должны использовать get('products') (в нижнем регистре).

Смежные вопросы