views:

869

answers:

3

I'd like to add an "onload" function to my custom Dojo class such that it can call functions that register to for the event - something like myWidget.addOnLoad(...)

My class is not a Dijit it's a simple class that uses dojo.declare. Upon creation several functions are called (xhr, etc) to initialize the class and I need the ability to notify other javascript functions that the widget is loaded & ready.

A: 

So I went ahead & basically copied the Dojo addOnLoad functions & added it to my class. It seems to be working. I looked at doing a pub/sub or a dojo.connect, but I feel like this was the cleanest, most recognizable solution.

Below are the necessary bits to get it going, again stripped out of dojo.js and plugged into my class:

_onto : function(arr, obj, fn){
 if(!fn){
  arr.push(obj);
 }else if(fn){
  var func = (typeof fn == "string") ? obj[fn] : fn;
  arr.push(function(){ func.call(obj); });
 }
},

_loaded : function() {
 this._loadNotifying = true;
 this._postLoad = true;
 var mll = this._loaders;
 for(var x = 0; x < mll.length; x++){
  try{
   mll[x]();
  }catch(e){
   throw e;
   console.error("addOnLoad callback failed: " + e, e); /* let other load events fire, like the parser, but report the error */
  }
 }
 this._loadNotifying = false;
 //Make sure nothing else got added to the onload queue
 //after this first run. If something did, and we are not waiting for any
 //more inflight resources, run again.
 if(this._postLoad && this._inFlightCount == 0 && mll.length){
  this._loaded();
 }
},

addOnLoad : function(/*Object?*/obj, /*String|Function?*/functionName){
 this._onto(this._loaders, obj, functionName); 
 if(this._postLoad && !this._loadNotifying){
  this._loaded();
 }
}
olore
I don't see how this would work. Are you calling _loaded outside of this code sample somewhere?
seth
seth you are right, I spared the huge chunk of code that runs before I call this._loaded() - suffice to say it gets called when all that code is done running.
olore
+2  A: 

Have you considered using dojo.publish() to publish a topic when the widget is ready? Or, if the other code has a reference to the widget, you can call an empty function on the widget instance when your widget is loaded (call it "loaded"), and then the other code that has a reference to the instance can dojo.connect to that widget instance's "loaded" method to get notified when the method is called.

jrburke
+1  A: 

As jburke already pointed out Dojo makes it easy for you: dojo.connect is all you need. Here's an example:

a = {
    loaded: function() { console.log('[a] loaded'); }
}
b = {
    dependentAction: function() { console.log('[b] dependentAction'); }
}
dojo.connect( a, 'loaded', b, 'dependentAction' );
a.loaded()
// prints:
// [a] loaded
// [b] dependentAction

And then just execute a.loaded() after you're done with loading a.

Maine
Maine, thanks for the clear example. I am still going to use addOnLoaded as the entry point, but just called dojo.connect() instead.
olore