我有一组在公共命名空间(js 全局)下构建的实用程序函数。
IE
// 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,然后将根对象推到最深的子文件夹中,并在不那么深的子文件夹中分支对象。
这对我的口味来说非常违反直觉并且容易出错(假设您有文件夹结构更深的组件)。
为了解决这个问题,我使用了带有 defers 和 Promise 的 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
这是一个相当狭窄的用例示例,因为大多数情况下您会很高兴在一些用户交互回调中或所有内容都已初始化的地方处理这些全局变量。否则,如果您想在早期阶段对初始化顺序进行细粒度控制,这可能是一个解决方案。