我在Dojo 1.7.2中使用AMD加载器创建了如下所示的Dojo小部件
var myCpane;
require([
"dijit/layout/ContentPane"
], function(ContentPane) {
myCpane = new ContentPane();
});
myCpane.startup(); // It gives 'myCpane' as undefined
在上面的例子中,在最后一个陈述中,变量' myCpane'如果我使用' myCpane.startup()'来到未定义'在' require()'里面回调函数然后,它将正常工作。
但我想用那个' myCpane'变量在'要求'之外。功能(由于多种原因)。我知道'要求()'由于Dojo的组件加载过程而延迟了回调函数执行。
我的问题是,
所以变量' myCpane'不会被定义为' undefined'当控件来自' require()'功能
=============================================== ============
为了解决这个问题,我编写了一个小函数来加载模块并等到模块加载完成
LoadModule: function(modulePath) { // modulePath = "dijit/layout/ContentPane"
var moduleObject = undefined;
require({async: false}, [modulePath], function(getModuleObject) {
moduleObject = getModuleObject;
});
// Wait until the module loads completes
while(moduleObject === undefined);
// Return the loaded module.
return moduleObject;
}
函数的输出总是执行while循环,控件永远不会进入' require()的回调函数来将值设置为变量" moduleObject" 。
当'要求()'函数会调用它的回调函数吗?我已经使用浏览器调试器窗口验证了文件' ContentPane.js'正确加载,但没有调用回调函数,如果我对while循环进行注释,则回调被正确调用。
在我的情况下控件何时进入回调函数?
答案 0 :(得分:3)
我不确定你要实现什么目标,但它会像a programming anti-pattern那样找我。无论如何,你可以通过dojo/_base/Deferred
:
require(["dojo/_base/Deferred"], function(Deferred) {
var deferred = new Deferred();
require(["dijit/layout/ContentPane"], function(ContentPane) {
var myCpane = new ContentPane();
deferred.resolve(myCpane); //resolve, i.e. call `then` callback
});
deferred.then(function(myCpane) {
console.log(myCpane);
myCpane.startup();
});
});
在jsFiddle上与它混淆:http://jsfiddle.net/phusick/HYQEd/
我还建议你考虑实现同样的两种策略中的一种:
ContentPane
id
并通过dijit的registry.byId()
获取其参考。在单独的模块中创建ContentPane
实例,并将其作为该模块的返回值公开:
// file: myCpane.js
define(["dijit/layout/ContentPane"], function(ContentPane) {
var myCpane = new ContentPane();
return myCpane;
});
// file: main.js
require(["./myCpane"], function(myCpane) {
myCpane.startup();
});
答案 1 :(得分:1)
我认为这更多地涉及范围问题然后是加载器问题;考虑
var x;
function foo() {
x = { bar : 1 };
}
// you wouldn't expect to have reference to x variable here
if(typeof x.bar == "undefined") console.log(x);
// foo() is called at a random time - or in dojo loader case, when modules are present
foo();
console.log(x.bar); // oohh now its there ^^
在这种情况下,x转换为myCpane,它在函数内声明为变量(var $$),当完成加载程序需要模块时,回调函数。
Deferred是一个不错的处理程序,如下所述。但是,如果您已经处于分离(异步)功能流中,那么会有轻微的开销。要获得完全控制权,请查看 require(),您也可以这样做:
var myCpane;
require({ async: false }, [
"dijit/layout/ContentPane"
], function(ContentPane) {
myCpane = new ContentPane();
});
// require does not return until module loading is done and callback executed
myCpane.startup();