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

10
我正在尝试扩展jQuery UI自动完成小部件。在我的自定义小部件中,我需要能够覆盖选择事件,并且最好还允许小部件的用户附加自己的处理程序到该事件上。
这是我尝试之一的jsfiddle: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 UI的autocompleteselect。这不是我想要的。

根据此帖子,我尝试在小部件中定义了一个_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个回答

10

搞定了!在第一个代码示例中,我只需要绑定到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小部件事件的事件名称是有命名空间的-保持在脑海中很重要!


感谢您分享这些信息。如果没有您的答案,我无法找到原因。 - David Chelliah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接