2012-06-11 16 views
21

Supponiamo che scrivo:Get collezione Meteor per nome

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

C'è un'API per accedere a tali collezioni per nome? Qualcosa come Meteor.Collection.get(name), dove name è "foos" o "bars"? So che potrei scrivere qualcosa di simile

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

e quindi utilizzare MyCollections[name], ma io preferisco usare un'API esistente se ne esiste uno.

risposta

3

Per quanto posso vedere nell'origine dello collection.js, al momento non c'è modo nell'API di ottenere una raccolta esistente per nome, una volta che è già stata inizializzata sul server. Probabilmente non sarebbe difficile aggiungere questa funzionalità.

Quindi, perché non forare Meteor e inviare una patch o creare un pacchetto intelligente e condividerlo, sono sicuro che ci sono altri là fuori che vorrebbero la stessa funzionalità.

+0

Accettando questa risposta, poiché si basa su una lettura di [l'origine] (https://github.com/meteor/meteor/blob/master/packages/mongo-livedata/collection.js). –

+7

lo trovi in ​​'Meteor.connection._mongo_livedata_collections' – nepjua

+0

@nepjua che non è la raccolta corretta, prova ad inserirli nella console javascript e vedrai che i dati vengono inseriti nel client ma non vengono inviati al server. – malhal

0

Piuttosto che guardare, ho appena fatto:

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

o, eventualmente, metterlo dentro un altro oggetto. Non ho davvero realizzato un oggetto collezione Collections.

+0

Giusto, so che posso farlo. Ma ho un gran numero di collezioni che condividono lo stesso codice, quindi mi piacerebbe fare riferimento a loro per nome. –

0

noti che hanno un valore di ritorno, in modo da poter fare solo

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

e utilizzare Patternsovunque.

E quando è necessario abbonarsi agli aggiornamenti del server, fornire "patterns" a Meteor.subscribe().


Se si dispone dello stesso codice per più raccolte, è probabile che si stia facendo qualcosa di sbagliato dal punto di vista dell'ingegneria del software; perché non utilizzare una singola raccolta con un campo type (o qualcos'altro che differenzia i documenti) e utilizzarla invece di utilizzare più raccolte?

+1

È bene sottolineare che sembra un'evidente omissione dall'OP, che la chiamata "nuova Mongo.Collection" restituisce un oggetto collezione. D'altra parte, fornire semplicemente il nome della raccolta a 'Meteor.subscribe()' potrebbe non funzionare se la funzione di pubblicazione usa un nome diverso. Vedi [Understanding Meteor publish/subscribe] (http://stackoverflow.com/a/21853298/1269037) per i dettagli. –

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

A giudicare da quello che fa il collection.js, la linea che usiamo per istanziare l'oggetto insieme apre una connessione al database e guarda per la collezione che corrisponde al nome che diamo. Quindi in questo caso viene effettuata una connessione e la raccolta "foos" è associata alle "barre" dell'oggetto Meteor.Collection. Vedi collection.js E remote_collection_driver.js all'interno del pacchetto mongo-livedata.

Come con MongoDB, mentre è possibile, non è necessario creare collezioni in modo esplicito. Come indicato nella documentazione MongoDB:

A collection is created when the first document is inserted.

Quindi, penso che quello che cercate è quello che hai già - a meno che non ho completamente frainteso quello che stai intenzioni.

0

Sembra che non ci sia modo di ottenere l'oggetto Meteor.Collection spostato senza salvarlo al momento della creazione, come altri hanno menzionato.

Ma c'è almeno un modo per elencare tutte le raccolte create e accedere effettivamente all'oggetto Mongo LocalCollection corrispondente.Sono disponibili da qualsiasi oggetto di Meteor Collection, quindi per mantenerlo generico puoi creare una collezione fittizia proprio per questo. Utilizzare un metodo come tale (CoffeeScript):

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

Questi oggetti non hanno tutti il ​​ritrovamento, findOne, aggiornare et al metodi, e anche alcuni che Meteor non sembra esporre, come pauseObservers e resumeObservers che ti interessa . Ma non ho provato a manipolare questo riferimento di LocalCollection di mongo direttamente per sapere se aggiornerà la raccolta del server di conseguenza.

+2

Nota: .collections è disponibile solo sul client, come parte di LocalCollectionDriver (https://github.com/meteor/meteor/blob/master/packages/mongo-livedata/local_collection_driver.js). Quindi questo approccio ti darebbe tutte le raccolte pubblicate sul client, ma non necessariamente tutte le raccolte in generale. – AlexeyMK

-2

Qualcuno ha trovato una soluzione per questo? Sarebbe bello per essere in grado di fare questo:

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

e hanno codice modello come

{{#each getCollection 'myCollection' }} 

Questo sarebbe davvero utile come ho notato alcune ridondanze che lo fanno w/meteora aiutanti template. ..

-2

È sempre possibile eseguire il rollover della raccolta automatica.

Supponiamo di avere un paio di raccolte denominate "Attività" e "Clienti". Metti un riferimento ciascuno in un oggetto "collezioni" e registra un helper di Handlebars per accedere a tali "raccolte" per collezioni ["nome"].

cioè mettere qualcosa di simile sul lato client main.js:

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

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

Poi, nel tuo HTML, basta fare riferimento alla raccolta per nome:

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

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

ma Guardate, non più generico " elenca tutti i record richiesti "boilerplate js!

15

Sulla base mongoinspector di Shane 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

Puoi fare lo stesso nel server, usando *** *** invece che *** *** ***. Il codice è lo stesso, basta sostituire *** *** *** *** con *** per ottenere gli oggetti di raccolta dallo spazio dei nomi globale. – Alberto

+2

Fuori dal contesto globale e in modalità rigorosa, usare 'var globals = Function ('return this')();' per ottenere un riferimento all'oggetto Global. Quindi sostituisci *** *** *** con *** globals *** nel codice. – Alberto

+0

Questo modello è utilizzato da [meteor-autocomplete] (https://github.com/mizzao/meteor-autocomplete/blob/master/autocomplete-server.coffee#L8). –

11

ho appena scoperto che il pacchetto: https://github.com/dburles/mongo-collection-instances/

Ti permette di

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 

auguriamo che contribuiscano

+2

Nota, questo pacchetto non è più necessario perché ora il recupero di raccolte esistenti è una funzione incorporata. – malhal

+0

@malhal hai un link che mostra, come farlo nella versione attuale? – Jankapunkt

+0

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

6

Questa funzione è stata aggiunta a M eteor nel febbraio 2016: "Provide a way to access collections from stores on the client"

Funziona così:

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

E mi stava usando come segue per testare inserti utilizzando la console javascript:

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

Per la inserirla è necessario il pacchetto insecure per essere installato, altrimenti viene visualizzato un messaggio di accesso negato.

+1

È possibile chiamare questo dal lato server e client? Ho provato questo codice e ottengo sempre ** TypeError: Impossibile leggere la proprietà '_stores' di undefined ** sul lato server. – grahan

1

Con https://github.com/dburles/mongo-collection-instances è possibile utilizzare Mongo.Collection.get('collectionname')

Nota che il parametro si sta inserendo è la stessa che si utilizza quando crea la collezione. Quindi se stai usando const Products = new Mongo.Collection('products') allora dovresti usare get('products') (in minuscolo).

Problemi correlati