扩展jQuery UI小部件 - 覆盖父事件?

Ser*_*y K 9 javascript jquery jquery-ui

我正在尝试扩展jQuery UI Autocomplete小部件.在我的自定义小部件中,我需要能够覆盖select事件,同时理想情况下还允许小部件的用户将自己的处理程序附加到该事件.

这是我尝试过的一个方面:http://jsfiddle.net/nN46R/

我的第一次尝试(在jsfiddle中)是绑定到以下事件_create:

$.widget("custom.myautocomplete", $.ui.autocomplete, {
    _create: function() {
        this._super("_create");

        // Doesn't work
        this.element.bind('autocompleteselect', function() {
            alert('Handling autocompleteselect!');
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

这没用.它如果你改变触发autocompleteselectselect,但只有当你选中文本框内的任何文字-但是这只是jQuery的选择处理程序射击,没有jQuery的用户界面的autocompleteselect.不是我想要的.

根据这篇文章,我尝试_select在窗口小部件中定义一个方法:

$.widget("custom.myautocomplete", $.ui.autocomplete, {
    _create: function() {
        this._super("_create");
    },
    _select: function (event, ui) {
        alert('Handling select!');
    }
});
Run Code Online (Sandbox Code Playgroud)

这也行不通.我尝试了同样的select(没有下划线),但没有运气.

唯一有效的方法是使用options数组传递默认处理程序,如此(jsfiddle):

$.widget("custom.myautocomplete", $.ui.autocomplete, {
    options: {
        select: function (event, ui) {
            alert('Handling select!');
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

但这有几个问题.首先,看起来不可能在处理程序中调用自定义小部件中的任何其他方法:

$.widget("custom.myautocomplete", $.ui.autocomplete, {
    options: {
        select: function (event, ui) {
            alert('Handling select!');

            // Doesn't work:
            // Uncaught TypeError: Object #<HTMLInputElement> has no method '_myCustomSelectHandler'
            this._myCustomSelectHandler();
        }
    },
    _myCustomSelectHandler: function (event, ui) {
        alert('In _myCustomSelectHandler!');
    }
});
Run Code Online (Sandbox Code Playgroud)

其次,如果用户定义了自己的select处理程序,那么我的将不会再触发:

$("#tags").myautocomplete({
    delay: 0,
    source: availableTags,
    select: function (e, ui) {
        alert("Muahaha! Me (the user) just overrode the select handler, and now yours won't get called!");
    }
});
Run Code Online (Sandbox Code Playgroud)

所以这看起来不像是一个解决方案.

那么,有什么方法可以扩展自动完成小部件并覆盖select处理程序?

Ser*_*y K 8

弄清楚了!在第一个代码示例中,我所要做的就是绑定到myautocompleteselect事件而不是autocompleteselect:

http://jsfiddle.net/nN46R/1/

$.widget("custom.myautocomplete", $.ui.autocomplete, {
    _create: function() {
        this._super("_create");

        // Works! Bind to the "myautocompleteselect" event, not
        // "autocompleteselect".
        this.element.bind('myautocompleteselect', function() {
            alert('Something selected!');
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

显然,引发的事件的全名是与事件名称连接的窗口小部件的名称(select).这是一个自定义小部件,因此您应该使用自定义小部件的名称,在我的示例中myautocomplete.

作为旁注,如果小部件用户想要绑定到代码中的任何事件,例如自动完成菜单打开或关闭,这也与小部件用户相关.如果这是基本自动完成小部件,他们将使用以下命令绑定到菜单打开事件:

$('#tags').bind('autocompleteopen', function(event, ui) {
    console.log('autocomplete menu opening');
});
Run Code Online (Sandbox Code Playgroud)

但是,如果他们使用自定义窗口小部件myautocomplete(扩展autocomplete),则需要绑定到myautocompleteopen事件:

$('#tags').bind('myautocompleteopen', function(event, ui) {
    console.log('custom autocomplete menu opening');
});
Run Code Online (Sandbox Code Playgroud)

jQuery UI小部件事件的事件名称是命名空间 - 请记住这一点非常重要!