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.

Was it helpful?

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();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top