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

时间:2014-02-06 16:18:40

标签: 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!');
        });
    }
});

这不起作用。如果您将autocompleteselect更改为select触发,但仅当您突出显示文本框中的任何文本时 - 但这只是jQuery的select处理程序触发,而不是jQuery用户界面autocompleteselect。不是我想要的。

根据this post,我尝试在窗口小部件中定义_select方法:

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

那也行不通。我只用select(没有下划线)尝试了相同的操作,但没有运气。

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

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

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

$.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!');
    }
});

其次,如果用户定义了自己的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!");
    }
});

所以这看起来不像解决方案。

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

1 个答案:

答案 0 :(得分: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!');
        });
    }
});

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

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

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

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

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

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