Dojo 1.7如何在require()之外使用dojo组件

时间:2012-05-17 07:13:23

标签: dojo amd

我在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的组件加载过程而延迟了回调函数执行。

我的问题是,

  1. 如何阻止'要求()'功能直到完成执行它的回调功能。
  2. 所以变量' 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循环进行注释,则回调被正确调用。

    在我的情况下控件何时进入回调函数?

2 个答案:

答案 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/

我还建议你考虑实现同样的两种策略中的一种:

  1. 授予ContentPane id并通过dijit的registry.byId()获取其参考。
  2. 在单独的模块中创建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();