Question

I'm using the latest qooxdoo SDK (3.5) and am trying to find a way to dynamically load a module. Each module would implement an "init" function which creates a window in the application and, from that point, is self-contained.

What I would need is the ability to call an arbitrary init function without knowing the module existed beforehand. For example, someone uploads a custom module and tries to run it--I just need to call the module's init function (or error out if the call fails).

Any ideas?

Edit:

Something like:

function loadModule(modName) {
  var mod = new qx.something.loadModule(modName);
  mod.init();
}
Was it helpful?

Solution

I found 3 ways that Qooxdoo has to run dynamic code. The first way is via the built-in parts loader. "Parts" are basically portions of an application that qooxdoo will load "just-in-time" when you actually need them--for example, a class that operates a rarely used form or dialog box. This method is not truly dynamic (in my opinion) in that it requires the code to be included in the build process that Qooxdoo provides. Explaining exactly how it works is out of scope for this answer and, frankly, I'm not yet all that familiar with it myself.

The second way is via the qx.Class.getByName() function call. It works like so:

qx.Class.define("Bacon", { 
  extend: qx.core.Object, 
  construct: function(foo, bar) { 
    this.foo = foo; 
    this.bar = bar; 
  } 
}); 

var klass = qx.Class.getByName("Bacon"); 
var obj = new klass("foo", "bar"); 
this.debug(obj.foo);

This method was found on the Qooxdoo mailing list here. This method will work for code included in the build process and for code introduced dynamically but, in my opinion, is trumped by the third method for the simple reason that if you are introducing a new class dynamically, you'll have to use the third method anyway.

The final method I located was actually revealed to me via studying the source code for the Qooxdoo playground. (The source code is available as part of the desktop download.)

The playground reads the code in from the editor and creates an anonymous function out of it, then executes the function. There is a bunch of setup and tear-down the playground does surrounding the following code, but I've removed it for brevity and clarity. If you are interested in doing something similar yourself, I highly recommend viewing the source code for the playground application. The dynamic code execution is contained within the __updatePlayground function starting on line 810 (Qooxdoo v3.5).

var fun;
try {
  fun = qx.event.GlobalError.observeMethod(new Function(code));
} catch(ex) {
  //do something with the exception
}

try {
  fun.call();
} catch(ex) {
  //do something with the exception
}

The code is straightforward and uses the built-in Javascript function "call" to execute the anonymous function.

OTHER TIPS

Please define module.

Qooxdoo source code uses the same convention as Java - one class per file. Do you really want to load classes individually and deal with dependencies? If not, what's your definition of a module?

Other than that, qooxdoo has a notion of packages, which are groups of classes, interfaces and mixins, framework, contribs, including the framework itself, packed by the generator in an optimized way, so that the classes used earlier are loaded earlier. Using qooxdoo's own packaging mechanism requires no more effort than running build with custom arguments or customizing the config.json - all described in detail in the manual.

If your idea of a module is sort of a sub-application, mostly decoupled from everything else in the big application, I'm not sure it's achievable without either significantly modifying the generator code (what ./generate.py calls) or accepting some size overhead.

I won't go into details of modifying the generator - if you go this route you'll need to dig deeply anyway, and you'll learn more than I know about the generator.

What you can do while staying within what qooxdoo allows is to create a separate island application for each module, build your own infrastructure for inter-modules communication via JavaScript attached to the top window, and run the modules inside the main page, with some manually added magic to make the various modules behave like tab panes or qooxdoo windows. The overhead you'll have to take, besides some awkward custom, non-qooxdoo code, is that all modules will re-load the qooxdoo framework code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top