Подтвердить что ты не робот

Глобальные переменные в Метеор

У меня

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

в одном файле и

var Collections = {};

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

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

в другом файле.

Я получаю ошибку ReferenceError: Schemas is not defined. Это довольно очевидно, что я должен определить Schemas в моем файле collections.js вместо того, чтобы разделить их. Но как Meteor работает с кодом в отдельных файлах? Я могу получить доступ к некоторым объектам и переменным, в то время как другие недоступны.

4b9b3361

Ответ 1

Когда вы определяете переменную в классическом стиле JavaScript:

var someVar = 'someValue';

в корне вашего файла .js Метеор привязывает его к файлу с помощью IIFE.

Если вы хотите определить глобальную переменную, просто не пишите var, давая:

someVar = 'someValue';

Это будет определять переменную во всех ваших приложениях по умолчанию, хотя вы можете ограничить ее, написав это объявление в определенной распознанной папке (client или server).

Однако эта переменная не будет определена в первую очередь. Он будет определен, когда Meteor запускает фактический код, который его определяет. Таким образом, это может быть не самая лучшая практика, потому что вы будете бороться с порядком загрузки, и это сделает ваш код зависимым от того, как Meteor загружает файлы: в какую папку вы вставляете файл, имя файла... Ваш код подвержен беспорядочным ошибкам, если вы слегка коснитесь своей архитектуры.

Как я уже сказал в другом близком сообщении, вы должны пойти на пакет напрямую!

Ответ 2

Переменные в Meteor, объявленные с помощью ключевого слова var, привязаны к файлу, в котором они объявлены.

Если вы хотите создать глобальную переменную, сделайте это

Schemas = {}

Ответ 3

ReferenceError является ошибкой Node. Метеор - это рама поверх Node.

Node имеет глобальную область действия (aka Node global). Эта ошибка вызывается Node (не Meteor), если вы пытаетесь получить доступ к глобальной переменной undefined.

Браузеры также имеют глобальную область видимости window и не бросают ReferenceErrors при доступе к переменным undefined.

Вот шаблон, который мне нравится для добавления функциональности в класс (это очень Метеор):

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

Это тривиальный пример. Что, если я не хочу беспокоиться о порядке загрузки? Почему не _.extend() в /lib/Helpers.js?

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

Потому что вы получите ReferenceError из Node, если Helpers не определены - в частности, "Помощники", используемые в качестве аргумента. (Node знает, как назначить помощников как global.Helpers).

Вот два способа "исправить":

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) работает в node, но глобальных браузеров нет. Поэтому он не справляется с этой задачей.

Итак, я сдался и вернулся к перезаписыванию его в первый раз в lib и искал ошибки во время выполнения, если что-то было перезаписано.

Если у вас есть удобный кросс-браузерный синтаксис для этого, сделайте комментарий:-)   var something = something || {}   something.blah = foo;

Вот некоторые другие Советы по сокращению JS.

Ответ 4

Переменные сеанса являются глобальными и могут быть легко доступны в разных файлах/функциях. Session.setPersistent используется для постоянного определения имени переменной во всех файлах. Можно ограничиться использованием переменных сеанса, когда их приложение слишком велико, поскольку они не удаляются и могут вызывать ошибку в консоли. Ссылка на документы: https://docs.meteor.com/api/session.html