web-dev-qa-db-ja.com

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
  }
});

1つのファイルで

var Collections = {};

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

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

別のファイルに。

エラーReferenceError: Schemas is not definedが表示されます。 collections.jsファイルでSchemasを個別に定義するのではなく、定義する必要があることはかなり明白です。しかし、Meteorは別々のファイルのコードをどのように使用しますか?一部のオブジェクトと変数にはアクセスできますが、他のオブジェクトと変数にはアクセスできません。

28
Jamgreen

従来のJavaScriptの方法で変数を定義する場合:

var someVar = 'someValue';

.jsファイルのルートで、Meteorは [〜#〜] iife [〜#〜] を使用してファイルにスコープします。

グローバル変数を定義したい場合、単にvarを書かないでください:

someVar = 'someValue';

これはデフォルトですべてのアプリケーションで変数を定義しますが、 特定の認識されたフォルダーにその宣言を書くことで制限できますclientまたはserverフォルダーなど)。

ただし、この変数は絶対に最初に定義されるわけではありません。 Meteorがそれを定義する実際のコードを実行するときに定義されます。したがって、ロード順序に苦労するため、ベストプラクティスではない可能性があり、コードは Meteorがファイルをロードする方法に依存します :ファイルを入れるフォルダ、ファイルの名前...アーキテクチャに少し手を加えると、コードが乱雑なエラーになりやすくなります。

別の密接に関連する投稿 で提案したように、直接パッケージに行くべきです!

57
Paul Stenne

varキーワードで宣言されたMeteorの変数は、それらが宣言されているファイルにスコープされます。

グローバル変数を作成する場合は、これを行います

Schemas = {}
11
Joshua Soileau

ReferenceError はNodeエラーです。MeteorはNode上のフレームワークです。

Nodeにはグローバルスコープ(Nodeのglobal変数)があります。 このエラーは、未定義のグローバル変数にアクセスしようとすると、Node)によってスローされます。

ブラウザにはwindowというグローバルスコープもあり、未定義の変数にアクセスしたときにReferenceErrorsをスローしません。

クラスに機能を追加するために私が好きなパターンは次のとおりです(非常にMeteorです):

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

これらの実装を検討してください。

// /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*/}

これは簡単な例です。ロード順を気にしたくない場合はどうすればよいですか? /lib/Helpers.jsで_.extend()を使用しないのはなぜですか?

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

NodeからReferenceErrorを取得します。(Nodeはヘルパーをglobal.Helpersとして割り当てることを知っています).

これを「修正」する2つの方法があります:

1)ヘルパーを何かに割り当てる

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

2)グローバルからのヘルパーを使用する

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

どちらも吸う

1)の構文は恐ろしいです。
2)ノードで動作しますが、ブラウザにはグローバルはありません。そのため、その目的は達成できません。

だから私はあきらめて、libで初めてそれを上書きし、何かが上書きされた場合のランタイムエラーを探しに戻りました。

これに便利なクロスブラウザ構文がある場合は、コメントをしてください:-) var something = something || {} something.blah = foo;

他にもいくつかあります JSの速記のヒント

3
Michael Cole

セッション変数はグローバルであり、異なるファイル/関数で簡単にアクセスできます。 Session.setPersistentは、すべてのファイルにわたって変数名を永続的に設定するために使用されます。アプリが大きすぎて削除されないためにセッション変数の使用を制限し(メモリリークが発生する可能性がある)、コンソールでエラーが発生する場合があります(未定義などの場合)。ドキュメントへのリンク: https://docs.meteor.com/api/session.html

1
user3807691