Javascript / Ajax - вручную удалить обработчик события из Sys.EventHandlerList () - PullRequest
1 голос
/ 31 декабря 2008

У меня есть два элемента управления сценарием, один содержит другой, и я успешно смог обработать события от дочернего элемента на родительском, используя:

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

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

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

Где addItemSelected (на дочернем элементе):

addItemSelected: function(handler) 
{

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

},

и getEvents:

getEvents: function() 
{

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

    return this._events;
},

Проблема в том, что при утилизации родителя я хочу сделать то же самое:

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

но .control больше не существует. Я предполагаю, что это потому, что дочерний элемент управления уже удален и, следовательно, свойство .control больше не работает.

В свете этого я решил запустить список дочерних событий и удалить все обработчики событий в нем.

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

        handler = list.getHandler(item);

        list.removeHandler(item, handler);
    }

    ....
}

Есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 09 января 2009

Я не уверен, что свойство "control" expando для элемента DOM является правильным способом ссылки на объект управления. Он управляется фреймворком, и, как вы видите, я думаю, что он уже исправлен к тому времени, когда ваше распоряжение называется.

Вы пытались использовать $find вместо $get и перерабатывать свои ссылки таким образом?:

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;
}

О, да, и где вы ссылаетесь на элемент DOM, хранящийся в this._autoComplete, вы вместо этого проходите сам объект управления:

this._autoControl.get_element();

Таким образом, по сути, инвертируйте логику «get element => get control object» в «get control object => get element».

...