2012-06-11 11 views
21

Angenommen, ich schreibe:Erhalten Meteor Sammlung von Namen

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

Gibt es eine API für diese Sammlungen durch seinen Namen zugreift? Etwas wie Meteor.Collection.get(name), wo name ist "foos" oder "bars"? Ich weiß, dass ich so etwas wie

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

schreiben konnte und dann MyCollections[name] verwenden, aber ich würde es vorziehen, eine vorhandene API zu verwenden, wenn ein solches vorhanden ist.

Antwort

3

Soweit ich in der collection.js Quelle sehe, gibt es derzeit keine Möglichkeit in der API eine vorhandene Sammlung nach Namen zu bekommen, sobald sie bereits auf dem Server initialisiert wurde. Es wäre wahrscheinlich nicht schwer, diese Funktion hinzuzufügen.

Also, warum nicht Meteor abzweigen und einen Patch einreichen oder ein intelligentes Paket erstellen und es teilen Ich bin mir sicher, es gibt andere da draußen, die die gleiche Funktion mögen.

+0

Diese Antwort wird akzeptiert, da sie auf der [Quelle] basiert (https://github.com/meteor/meteor/blob/master/packages/mongo-livedata/collection.js). –

+7

fand es auf 'Meteor.connection._mongo_livedata_collections' – nepjua

+0

@nepjua das ist nicht die richtige Sammlung, versuchen, es in der Javascript-Konsole einzufügen, und Sie werden sehen, dass die Daten in den Client einfügen, aber nicht an die gesendet werden Server. – malhal

0

Anstatt suchen, ich habe gerade dabei sind:

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

oder möglicherweise in einem anderen Objekt setzen es. Ich habe nicht wirklich ein Collection-Objekt erstellt.

+0

Richtig, ich weiß, dass ich das tun kann. Aber ich habe eine große Anzahl von Sammlungen, die denselben Code haben, daher möchte ich sie mit ihrem Namen referenzieren. –

0

Beachten Sie, dass sie einen Rückgabewert haben, so können Sie tun nur

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

und verwenden Patternsüberall.

Wenn Sie Server-Updates abonnieren müssen, geben Sie "patterns" an Meteor.subscribe().


Wenn Sie den gleichen Code für mehrere Sammlungen haben, ist die Chance groß, dass Sie etwas falsch von einer Software-Engineering-Sicht tun; Warum verwenden Sie nicht eine einzelne Sammlung mit einem Feld type (oder etwas anderes, das die Dokumente unterscheidet) und verwenden Sie das, anstatt mehrere Sammlungen zu verwenden?

+1

Gut, um darauf hinzuweisen, was offensichtlich eine Unterlassung von der OP ist, dass der 'neue Mongo.Collection' Aufruf ein Sammlungsobjekt zurückgibt. Auf der anderen Seite funktioniert die Angabe des Sammlungsnamens für "Meteorsubscribe()" möglicherweise nicht, wenn die Veröffentlichungsfunktion einen anderen Namen verwendet. Einzelheiten finden Sie unter [Understanding Meteor publish/subscribe] (http://stackoverflow.com/a/21853298/1269037). –

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

nach zu urteilen, was die collection.js der Fall ist, die Linie, die wir das Sammelobjekt zu instanziiert verwenden öffnet eine Verbindung zur Datenbank und sucht nach der Sammlung den Namen passend wir geben. In diesem Fall wird eine Verbindung hergestellt und die Sammlung "foos" wird an das Meteor.Collection-Objekt "bars" gebunden. Siehe collection.js UND remote_collection_driver.js innerhalb des Mongo-Livedata-Pakets.

Wie bei MongoDB, müssen Sie, während Sie können, keine Sammlungen explizit erstellen. Wie in der Dokumentation MongoDB angegeben:

A collection is created when the first document is inserted.

Also, ich glaube, was du bist nach ist das, was Sie bereits haben - es sei denn, ich völlig falsch verstanden haben, was Sie Absichten sind.

0

Es scheint, dass es keine Möglichkeit gibt, das umschlossene Meteor.Collection-Objekt zu bekommen, ohne es zur Erstellungszeit zu speichern, wie andere bereits erwähnt haben.

Aber es gibt zumindest eine Möglichkeit, alle erstellten Sammlungen aufzulisten und tatsächlich auf das entsprechende Mongo LocalCollection-Objekt zuzugreifen.Sie stehen in jedem Meteor Collection-Objekt zur Verfügung. Um es also generalistisch zu halten, können Sie einfach eine Dummy-Sammlung erstellen. Verwenden Sie eine Methode als solche (Coffee):

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

Diese Objekte haben alle die Entdeckung, FindOne, aktualisieren et al Methoden und sogar einige, die Meteor scheint nicht zu belichten, wie pauseObservers und resumeObservers die interessant scheinen . Aber ich habe nicht versucht, mit dieser mongo LocalCollection-Referenz direkt zu experimentieren, um die Server-Sammlung entsprechend zu aktualisieren.

+2

Hinweis: .collections ist nur auf dem Client als Teil von LocalCollectionDriver verfügbar (https://github.com/meteor/meteor/blob/master/packages/mongo-livedata/local_collection_driver.js). Mit diesem Ansatz erhalten Sie alle Sammlungen, die dem Kunden veröffentlicht wurden, aber nicht unbedingt alle Sammlungen insgesamt. – AlexeyMK

-2

Hat jemand eine Lösung dafür? Es wäre toll, der Lage sein, dies zu tun:

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

und Template-Code wie

{{#each getCollection 'myCollection' }} 

haben, die wirklich nützlich sein würde, wie ich einige Redundanzen bemerkt haben es w/Meteor Vorlage Helfer tun. ..

-2

Sie können immer Ihre eigenen automatischen Sammlung Getter rollen.

Angenommen, Sie haben ein paar Sammlungen namens "Unternehmen" und "Kunden". Setzen Sie jeweils eine Referenz in ein Objekt "Sammlungen" und registrieren Sie einen Handlebars-Helfer, um auf diese "Sammlungen" durch Sammlungen ["Name"] zuzugreifen.

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

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

Dann in Ihrem HTML, nur auf die Sammlung von Namen verweisen:

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

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

Schauen Sie MA, nicht mehr generic "

also so etwas wie dies auf der Client-Seite main.js setzen listet alle Datensätze auf "boilerplate js erforderlich!

15

Basierend auf Shane Donelley der mongoinspector 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

Sie können dasselbe auf dem Server tun, indem Sie *** this *** anstelle von *** window *** verwenden. Der Code ist derselbe, ersetzen Sie einfach *** window *** durch *** this ***, um die Auflistungsobjekte aus dem globalen Namespace abzurufen. – Alberto

+2

Außerhalb des globalen Kontexts und im strikten Modus verwenden Sie 'var globals = Function ('return this')();', um einen Verweis auf das globale Objekt zu erhalten. Ersetzen Sie also *** window *** durch *** globals *** im Code. – Alberto

+0

Dieses Muster wird von [meteor-autocomplete] (https://github.com/mizzao/meteor-autocomplete/blob/master/autocomplete-server.coffee#L8) verwendet. –

11

Ich habe gerade das Paket: https://github.com/dburles/mongo-collection-instances/

Es Sie

erlauben
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 

Hoffnung wird es

+2

Beachten Sie, dass dieses Paket nicht mehr benötigt wird, da das Abrufen vorhandener Sammlungen jetzt eine integrierte Funktion ist. – malhal

+0

@malhal Hast du einen Link, der zeigt, wie man das in der aktuellen Version macht? – Jankapunkt

+0

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

6

helfen Diese Funktion wurde zu M hinzugefügt eteor im Februar 2016: "Provide a way to access collections from stores on the client"

Es funktioniert wie folgt:

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

Und ich benutzte es wie folgt Einsätze zu testen, die JavaScript-Konsole:

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

Für die Fügen Sie es ein, das insecure Paket benötigt, um noch installiert zu werden, andernfalls erhielt eine Zugang verweigert Nachricht.

+1

Ist es möglich, dies von der Server- und Clientseite aus aufzurufen? Ich habe diesen Code ausprobiert und bekomme immer ** TypeError: Kann die Eigenschaft '_stores' von undefined ** auf der Serverseite nicht lesen. – grahan

1

Mit https://github.com/dburles/mongo-collection-instances können Sie Mongo.Collection.get('collectionname')

Hinweis verwenden, dass der Parameter Sie Einfügen die gleiche ist, die Sie verwenden, wenn die Sammlung zu schaffen. Wenn Sie also const Products = new Mongo.Collection('products') verwenden, sollten Sie get('products') (Kleinbuchstaben) verwenden.

Verwandte Themen