У меня есть набор служебных функций, которые я структурировал в общем пространстве имен (js global).
I.e.
// utils/utils.js
Utils = {};
а затем в подпапках:
// utils/validation/validation.js
Utils.Validation = {};
// utils/validation/creditCard.js
Utils.Validation.creditCard = ... // validation logic etc
также у меня есть куча кода, который использует Utils и его подобъекты.
Очевидно, что эта структура не работает, так как Meteor сначала загружает подпапки.
Чтобы заставить его работать как положено, мне пришлось создать /subfolder/subfolder/subfolder с бессмысленными именами, а затем засунуть корневой объект в самую глубокую подпапку, а объекты ветвления в подпапки не так глубоко.
На мой вкус, это крайне нелогично и подвержено ошибкам (предположим, у вас есть компонент, который находится еще глубже в структуре папок).
Чтобы решить эту проблему, я использовал библиотеку Q с отсрочками и обещаниями. Решение все еще не является чистым, поскольку оно заставляет вас повторять рутинный код и выполнять проверки, но оно дает вам полный контроль над порядком загрузки, не вмешиваясь в структуру каталогов (привет тем, кто говорит, что вы можете организовать код метеора, как хотите).
Пример:
//utils.js
UtilsDefer = UtilsDefer || Q.defer();
UtilsDefer.resolve({
// here some root utils stuff
});
//cards.js
// here we'll depend on Utils but don't want to care about directory structure
UtilsDefer = UtilsDefer || Q.defer(); // it will be a) already
// resolved defer from utils.js, or b) new defer that will
// be resolved later in utils.js
UtilsDefer.then(function(Utils) {
// do something with utils usage, or for instance add some fields here
Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer();
Utils.CreditCardDefer.resolve({
// Credit card utils here
})
});
//someOtherFile.js
// it will be pain to use sub-objects with this method though:
UtilsDefer = UtilsDefer || Q.defer();
UtilsDefer.then(function(Utils) {
Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer();
Utils.CreditCardDefer.then(function(CreditCard) {
// do stuff with CreditCard _if_ you need to do it on startup stage
})
});
Это пример довольно узкого варианта использования, так как в основном вы будете довольны обработкой этих глобальных переменных внутри некоторых обратных вызовов взаимодействия с пользователем или Meteor.startup
, где все уже инициализировано. В противном случае, если вам нужен детальный контроль над порядком инициализации на очень ранней стадии, это может быть решением.
person
Igor Loskutov
schedule
05.04.2015