2014-12-16 21 views
25

Ich habeGlobale Variablen in Meteor

var Schemas = {}; 

Meteor.isClient && Template.registerHelper("Schemas", Schemas); 

Schemas.Person = new SimpleSchema({ 
    fullName: { 
    type: String, 
    index: 1, 
    optional: true, 
    }, 
    email: { 
    type: String, 
    optional: true 
    }, 
    address: { 
    type: String, 
    optional: true 
    }, 
    isActive: { 
    type: Boolean, 
    }, 
    age: { 
    type: Number, 
    optional: true 
    } 
}); 

in einer Datei und

var Collections = {}; 

Meteor.isClient && Template.registerHelper("Collections", Collections); 

Persons = Collections.Persons = new Mongo.Collection("Persons"); 
Persons.attachSchema(Schemas.Person); 

in einer anderen Datei.

Ich bekomme den Fehler ReferenceError: Schemas is not defined. Es ist ziemlich offensichtlich, dass ich Schemas in meiner collections.js Datei definieren muss, anstatt sie zu trennen. Aber wie arbeitet Meteor mit Code in separaten Dateien? Ich kann auf einige Objekte und Variablen zugreifen, während andere nicht zugänglich sind.

+0

ist 'Schemas' eine globale Variable? Laden Sie es mit 'require'? Vielleicht müssen Sie uns mehr Code zeigen, denn da der Code geschrieben ist, sollte es keine Probleme geben –

+3

mögliche Duplikate von [Wie kann ich auf Konstanten in der Datei lib/constants.js in Meteor zugreifen?] (http://stackoverflow.com/ Fragen/26836390/how-can-i-Zugriff-Konstanten-in-der-Lib-Konstanten-js-Datei-in-Meteor) –

Antwort

53

Wenn Sie eine Variable im klassischen JavaScript Art und Weise definieren:

var someVar = 'someValue'; 

an der Wurzel Ihrer .js Datei Meteor Tive es in die Datei ein IIFE verwenden.

Wenn Sie eine globale Variable definieren möchten, einfach nicht schreiben die var, geben:

someVar = 'someValue'; 

Dies wird eine Variable in Ihre Anwendung standardmäßig definieren, obwohl Sie es durch das Schreiben beschränken kann, dass Erklärung in einem specific recognized folder (client oder server Ordner zum Beispiel).

Diese Variable wird jedoch nicht absolut zuerst definiert. Es wird definiert, wenn Meteor den eigentlichen Code ausführt, der es definiert. Daher ist es möglicherweise nicht die beste Vorgehensweise, da Sie mit der Ladereihenfolge zu kämpfen haben, und Ihr Code wird davon abhängig gemacht, wie Meteor loads files: in welchen Ordner Sie die Datei einfügen, den Namen der Datei ... Ihr Code ist anfällig für unordentliche Fehler, wenn Sie Ihre Architektur leicht berühren.

Wie ich in another closely related post vorgeschlagen habe, sollten Sie für ein Paket direkt gehen!

+0

Ich versuche, meine globalen Variablen im Verzeichnis lib zu definieren, aber Pakete sind definitiv robuster – CleoR

+3

I Ich möchte hinzufügen, dass das wirklich cool ist, weil Sie eine constants.js-Datei in Ihrem/client und eine andere in Ihren/server-Verzeichnissen haben können. Und wenn Sie eine Konstantendatei zwischen beiden teilen möchten, können Sie sie in/lib/constants erstellen. –

+0

Dies ist kein Meteor-Problem. Siehe unten für ReferenceError. –

11

Variablen in Meteor mit dem var Schlüsselwort deklariert in die Datei scoped werden sie in deklariert sind.

Wenn Sie eine globale Variable tun dies

Schemas = {} 
+3

Ich bin mir nicht sicher, was ich davon halte ... gibt es keine ES6/Webpack-Art, Variablen aus einer anderen Datei zu importieren, so dass ich Globals vermeiden kann? – Andy

2

ReferenceError ist ein Knoten Fehler erstellen möchten. Meteor ist ein Framework auf dem Knoten.

Knoten hat einen globalen Geltungsbereich (alias Node global Variable). Dieser Fehler wird von Node (nicht Meteor) ausgelöst, wenn Sie versuchen, auf eine undefinierte globale Variable zuzugreifen.

Browser haben auch einen globalen Bereich namens window und werfen keine ReferenceErrors, wenn auf undefinierte Variablen zugegriffen wird.

Hier ist ein Muster Ich mag Funktionalität zu einer Klasse für das Hinzufügen (es ist sehr Meteor):

/lib/Helpers.js  <-- Helpers for everyone (node+browser) 
/server/Helpers.js <-- Server helpers (node) 
/client/Helpers.js <-- Client helpers (browser) 

diese Implementierungen Bedenken Sie:

// /lib/Helpers.js 
Helpers = {/* functions */}; // Assigned to window.Helpers and global.Helpers 

// /server/Helpers.js 
Helpers = _.extend(Helpers, {/*more functions*/} 

// /client/Helpers.js 
Helpers = _.extend(Helpers, {/*more functions*/} 

Dies ist ein triviales Beispiel ist.Was ist, wenn ich mich nicht um die Ladereihenfolge kümmern möchte? Warum nicht _.extend() in /lib/Helpers.js?

// /lib/Helpers.js 
// Helpers = {/* functions */};     // Overwrites... 
Helpers = _.extend(Helpers, {/* functions */}); // ReferenceError 

Da Sie eine Reference von Knoten erhalten, wenn Helfer nicht definiert ist - speziell die „Helfer“ als Argument verwendet. (Der Knoten kann Helfer als global.Helpers zuweisen).

Hier sind zwei Möglichkeiten zu "reparieren" auswählen:

1) zuordnen Helfer etwas

// /lib/Helpers.js 
// Helpers = Helpers || {} // would be another ReferenceError 
if (typeof Helpers === 'undefined') Helpers = {}; 
Helpers = _.extend(Helpers, {/* functions */}); 

2) Verwenden Helfer aus der globalen

// /lib/Helpers.js 
Helpers = _.extend(global.Helpers, {/* functions */}); // works in node, but... 

Beide welche saugen.

1) Die Syntax ist schrecklich.
2) funktioniert in Knoten, aber es gibt keine globalen in Browsern. So versagt es seinen Zweck.

Also gab ich auf und ging wieder zu überschreiben es das erste Mal in lib, und auf der Suche nach Laufzeitfehlern, wenn etwas überschrieben wurde.

Wenn Sie eine handliche Cross-Browser-Syntax dafür haben, kommentieren Sie :-) var etwas = etwas || {} something.blah = foo;

Hier sind einige andere JS shorthand tips.

+0

Beachten Sie, dass der dritte Teil des Codes am Anfang jeder Datei hinzugefügt werden muss, die eine globale Variable für jede Variable verwenden muss. –

+1

Können Sie erklären, warum Sie auf ES6 verwiesen haben und wie das für die Frage relevant ist? – Fletch

+0

@Fletch umm ... eigentlich nicht. Also habe ich es entfernt. Aus irgendeinem Grund dachte ich, ES6-Module würden helfen, den globalen Namensraum aufzuräumen, aber ich kann nichts darüber finden: - / –

0

Sitzungsvariablen sind global und können problemlos in verschiedenen Dateien/Funktionen aufgerufen werden. Session.setPersistent wird verwendet, um den Variablennamen dauerhaft für alle Dateien festzulegen. Man könnte die Verwendung von Sitzungsvariablen einschränken, wenn ihre App zu groß ist, da sie nicht gelöscht werden und möglicherweise einen Fehler in der Konsole verursachen. Link zur Dokumentation: https://docs.meteor.com/api/session.html