Глобальные переменные в Метеор
У меня
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 работает с кодом в отдельных файлах? Я могу получить доступ к некоторым объектам и переменным, в то время как другие недоступны.
Ответы
Ответ 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