您可以在define函数中进行模块初始化,并在define([..]中指定它的依赖关系:
//Module A
define(['SomeModule'], function(SomeModule){
// initialization of the module
return {
//initializedModuleInterface..
};
});
如果您偶然发现模块之间的循环依赖关系,那么您可以在从模块返回的接口中,推迟对第二个模块的需要,直到使用模块提供的功能,例如,通过要求它不在define([..] 但是当模块本身被使用时:require("a").doSomething();
//Inside b.js:
define(["require", "a"],
function(require, a) {
//"a" in this case will be null if "a" also asked for "b",
//a circular dependency.
return function(title) {
return require("a").doSomething();
}
}
);
http://requirejs.org/docs/api.html#circular
How to handle circular dependencies with RequireJS/AMD?
初始化参数本身可以是另一个提供配置参数的模块。
编辑 1:添加 requirejs 作为动态模块定义器和加载器的用法
如果需要动态依赖注入机制的结构,你仍然可以使用requirejs。不确定它是否是为它设计的:
1 .当你手头有必要的配置变量时,然后通过 requirejs 进行动态模块定义
例如:
angular.module('myModule')
.run(function () {
define('myConf', [], function() {
return {
confA: 1,
confB: 2
};
});
});
2 。在依赖myConf 模块的模块中照常执行:
// Module: ModuleA
define(['myConf', function(myConf) {
// initialization with myConf values.
console.log(myConf.confA);
return some_interface;
});
或
define(function(require) {
var myConf = require('myConf');
console.log(myConf.confA);
// initialization with myConf values.
return some_interface;
});
3 .在应用程序的生命周期中,当需要ModuleA、ModuleB.. 时:
var moduleReq = 'moduleA';
require([moduleReq], function (moduleA) {
// doSomething with moduleA
});
这里的诀窍是dynamic defining of a module with a specific name 通过define('myConf', [], function() {..})。它使您无需文件即可在应用程序的生命周期内随时动态定义模块。据我了解,它主要用于 requirejs 捆绑解决方案。
编辑 2:第二种方法 - 在 requirejs 模块中使用 Promise 作为内部依赖管理。
可以使用的另一种方法是在 requirejs 模块中使用 Promise 来指定要等待的依赖项。
我们可以将模块主构造定义为一个 Promise,并在我们拥有必要的数据时通过接口 init 函数解决它。
1 .我们像往常一样将每个模块指定为系统中的一个文件。
2 .在我们想要动态初始化的confModule 中,我们以这种模式构建它:
// confModule
define([], function () {
var resolveMain;
var rejectMain;
var promise = new Promise(resolve, reject) {
resolveMain = resolve;
rejectMain = reject;
}
return {
init: function (confVarA, confVarB) {
try {
var moduleInitialized = {
// some preparation of confModule
confVarA: confVarA,
confVarB: confVarB
};
resolve(moduleInitialized);
}
catch (e) {
rejectMain(e);
}
},
then: function (successFn, errorFn) {
return promise.then(successFn, errorFn);
}
}
});
我们解决了outside of the constructor 的承诺。附加链接提供了有关该模式的好处和缺陷的更多信息。
3 .在依赖模块中,我们以相同的模式定义它们,不需要 init 功能,并添加等待 confModule 的承诺:
// moduleA
define(['confModule'], function (confModule) {
var resolveMain;
var rejectMain;
var promise = confModule.then(function(confModuleData) {
var moduleBInterface = {
// prepare module b
};
return moduleBInterface; // this make the promise return another promise to wait on for moduleBInterface return;
};
return {
then: function (successFn, errorFn) {
return promise.then(successFn, errorFn);
}
}
});
4 .在我们的代码中,当我们有我们需要的数据时,我们可以初始化 confModule:
define(['confModule', function (confModule) {
// some async get of confData
$.get(url, function (data) {
confModule.init(data.a, data.b);
});
});
5.在我们的代码中,当使用 moduleA 时,我们需要将其用作一个 Promise:
define(['moduleA'], fucntion (moduleA) {
moduleA.then(function (moduleAInteface) {
// do something with moduleA.
});
});