How do I add “onload” to my Dojo class?
-
12-09-2019 - |
Question
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.
Solution
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
.
OTHER TIPS
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.
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();
}
}