views:

1138

answers:

1

I have two scriptcontrols, one holds the other, and I have successfully been able to handle events from the child on the parent using:

initialize: function() 
{
    this._autoComplete = $get(this._autoCompleteID);

    this._onAutoCompleteSelected = Function
      .createDelegate(this, this.handleAutoCompleteSelected);

    var autoControl = this._autoComplete.control;
    autoControl.addItemSelected(this._onAutoCompleteSelected);
    ...
}

Where addItemSelected(on the child) is:

addItemSelected: function(handler) 
{

    list = this.getEvents();
    list.addHandler('userItemSelected', handler);

},

and getEvents is:

getEvents: function() 
{

    if (this._events == null) 
    {
        this._events = new Sys.EventHandlerList();
    }

    return this._events;
},

Problem is that on dispose of the parent, I want to do the same thing:

dispose: function() 
{
    var autoControl = this._autoComplete.control;
    autoControl.removeItemSelected(this._onAutoCompleteSelected);
    ...
}

but .control no longer exists. I am guessing this is because the child control has already been disposed and thus the .control property no longer works.

In light of this, I decided to run though the event list on the child and remove all the event handlers in it.

dispose: function() 
{
    list = this.getEvents();
    for(var item in list._list)
    {
        var handler;

        handler = list.getHandler(item);

        list.removeHandler(item, handler);
    }

    ....
}

Is there a better way to do this?

A: 

I'm not sure that the "control" expando property on the DOM element is the right way to reference the control object. It is managed by the framework and as you're seeing, I think it's already munged by the time your dispose is called.

Have you tried using $find instead of $get and reworking your references this way?:

initialize: function() 
{
    this._autoControl = $find(this._autoCompleteID);

    this._onAutoCompleteSelected = Function
      .createDelegate(this, this.handleAutoCompleteSelected);

    this._autoControl.addItemSelected(this._onAutoCompleteSelected);
}

dispose: function() 
{
    this._autoControl.removeItemSelected(this._onAutoCompleteSelected);
    this._autoControl = null;
}

Oh yeah and where you reference the DOM element stored in this._autoComplete you instead go through the control object itself:

this._autoControl.get_element();

So basically invert the logic of "get element => get control object" to "get control object => get element".

Crescent Fresh