tags:

views:

75

answers:

2

I've been trying to use dojo.require(If) with a local variable to dynamically load a module on a page based on a condition.

// note: dojo v1.4
djConfig = {
  debugAtAllCosts: true
};

Example 1 (does not work):

(function() {
  var nameOfClass = "Two";
  dojo.require("my.namespace." + nameOfClass);
  dojo.addOnLoad(function() {
    var oneOrTwo = new my.namespace[nameOfClass]();
  });
}());

Error: ReferenceError: nameOfClass is not defined.

Example 2 (does not work):

(function() {
  var nameOfClass = "Two";
  dojo.requireIf(nameOfClass == "One", "my.namespace.One");
  dojo.requireIf(nameOfClass == "Two", "my.namespace.Two");
  dojo.addOnLoad(function() {
    var oneOrTwo = new my.namespace[nameOfClass]();
  });
}());

Error: ReferenceError: nameOfClass is not defined.

Example 3 (works):

(function() {
  window.nameOfClass = "Two";
  dojo.requireIf(window.nameOfClass == "One", "my.namespace.One");
  dojo.requireIf(window.nameOfClass == "Two", "my.namespace.Two");
  dojo.addOnLoad(function() {
    var oneOrTwo = new my.namespace[nameOfClass]();
  });
}());

For some reason, it appears as though require and requireIf only allow global variables inside them. Is that a current limitation, or am I just doing something wrong?


Update 1:

Therefore, if I understand you (@Maine, @jrburke) correctly, this is a limitation of the debugAtAllCosts? If the above code is built as cross-domain (adding the xd file prefix / suffix) and is executed -- it will work as expected?

If that is the case, then what is the proper way of locally testing code that will be executed as cross-domain, without making the actual build?

That also makes me question the motivation for pre-parsing the dojo.require(s). If the loader_xd will not (or rather can not) pre-parse, why is the method that was created for testing/debugging doing so?

Update 2:

Since the two questions in the Update 1 above are not closely related to this one, I've moved them out into a separate discussion.

A: 

This is because requireIfs are parsed with regexps as the very first thing, and executed before the normal program flow.

If you'll grep Dojo source for requireIf, you should find this kind of lines handling it (loader_xd.js):

var depRegExp = /dojo.(require|requireIf|provide|requireAfterIf|platformRequire|requireLocalization)\s*\(([\w\W]*?)\)/mg;

The condition is then executed with eval in global scope, and not as a part of normal flow.

Maine
+1  A: 

To clarify more of what Main said, this is an issue with the XD loader in Dojo. debugAtAllCosts: true uses the XD Loader. If you just use the normal Dojo loader without debugAtAllCosts, it is not an issue. Also, attaching the module module name as a property on a publicly visible module would also avoid the issue.

jrburke
Thank you @jrburke, but using the normal dojo loader will not allow to test the behavior of the code as it will be executed after the xd build; since the former will use synchronous xhr to retrieve dojo.require[s], rather than the asynchronous 'script' inclusion (which loader_xd) uses.
GeorgeCalm