Как обрабатывать события в виджетах jQuery UI

Я пытаюсь написать виджет jQuery, следуя заданной модели здесь. Вот снимок виджета:

(function ($) {
    $.widget("ui.notification", {
        _create: function () {
            if (!this.element.hasClass("ntfn")) {
                this.element.addClass("ntfn");
            }

            this.elTitle = this.element.append("<div class='ntfn-title'>Notifications</div>");

            this.elTitle.click(this._titleClick)
        },
        _titleClick: function () {
            console.log(this);
        }
    });
})(jQuery);

здесь проблема заключается в области " это " внутри _titleClick метод внутри метода это указывает на title элемент. Но мне нужно, чтобы он указал на widget элемент.

Я думаю, что один из способов сделать это будет использовать класс-оболочку, как

var that = this;
this.elTitle.click(function() {
    that._titleClick.apply(that, arguments);
});

это лучший способ решить эту проблему или нет есть общая схема решения этой проблемы?

7 ответов


использовать this._on() метод для привязки обработчика. Этот метод предоставляется фабрикой виджетов jQuery UI и гарантирует, что в функции обработчика this всегда ссылается на экземпляр виджета.

_create: function () {
    ...
    this._on(this.elTitle, {
        click: "_titleClick" // Note: function name must be passed as a string!
    });
},
_titleClick: function (event) {
    console.log(this);       // 'this' is now the widget instance.
},

вы должны посмотреть на jQuery.proxy ()http://api.jquery.com/jQuery.proxy/

el.bind('evenname', $.proxy(function () {
   this.isMyScope.doSomething();
}, scope));

Я написал свой собственный метод для решения этой проблемы

_wrapCallback : function(callback) {
    var scope = this;
    return function(eventObject) {
        callback.call(scope, this, eventObject);
    };
}

в вашей функции create, init (или где-то в вашем экземпляре) сделайте следующее:

        _create: function() {

        ...

        // Add events, you will notice a call to $.proxy in here. Without this, when using the 'this'
        // property in the callback we will get the object clicked, e.g the tag holding the buttons image
        // rather than this widgets class instance, the $.proxy call says, use this objects context for the the 'this'
        // pointer in the event. Makes it super easy to call methods on this widget after the call.
        $('#some_tag_reference').click($.proxy(this._myevent, this));

        ...

        },

теперь определите свой объект event hander следующим образом:

        _myevent: function(event) {

            // use the this ptr to access the instance of your widget
            this.options.whatever;
        },

определение var scope=this, и использовать объем в обработчик событий.

    _create: function () {           
        var scope = this;
        $(".btn-toggle", this.element).click(function () {
            var panel = $(this).closest(".panel");
            $(this).toggleClass("collapsed");
            var collapsed = $(this).is(".collapsed");
            scope.showBrief(collapsed);
        });
    },

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

// using click in jQuery version 1.4.3+.
var eventData = { 'widget': this };

// this will attach a data object to the event,
// which is passed as the first param to the callback.
this.elTitle.click(eventData, this._titleClick);

// Then in your click function, you can retrieve it like so:
_titleClick: function (evt) {
    // This will still equal the element.
    console.log(this);
    // But this will be the widget instance.
    console.log(evt.data.widget);
};

раньше это было через jquery bind методом on приветствуется.

по состоянию на jQuery 1.7, то .на() метод является предпочтительным методом для присоединение обработчиков событий к документу. Для более ранних версий, .метод bind () используется для присоединения обработчика событий непосредственно к элементы. Обработчики прикрепляются к выбранным элементам в объект jQuery, поэтому эти элементы должны существовать в момент вызова к.связывать() происходит. Для более гибкой привязки событий см. обсуждение делегирование события в .on () or .делегат.)(

_create: function () {
   var that = this; 
   ...
   elTitle.on("click", function (event) {
             event.widget = that;   // dynamically assign a ref (not necessary)
             that._titleClick(event);
    });
},
_titleClick: function (event) {
    console.log(this);             // 'this' now refers to the widget instance.
    console.log(event.widget);     // so does event.widget (not necessary)
    console.log(event.target);     // the original element `elTitle`
},