我正在尝试按照给定here的模型编写一个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
方法中“this”的范围,在方法内部指向title
元素。但我需要它指向widget
元素。
我认为这样做的一种方法是使用像
这样的包装类var that = this;
this.elTitle.click(function() {
that._titleClick.apply(that, arguments);
});
这是解决此问题的最佳方法,还是有任何解决此问题的一般模式?
答案 0 :(得分:19)
使用this._on()
method绑定处理程序。此方法由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.
},
答案 1 :(得分:5)
您应该查看jQuery.proxy()http://api.jquery.com/jQuery.proxy/
el.bind('evenname', $.proxy(function () {
this.isMyScope.doSomething();
}, scope));
答案 2 :(得分:3)
我自己写了一个解决这个问题的方法
_wrapCallback : function(callback) {
var scope = this;
return function(eventObject) {
callback.call(scope, this, eventObject);
};
}
答案 3 :(得分:2)
在你的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));
...
},
现在定义你的对象事件处理者:
_myevent: function(event) {
// use the this ptr to access the instance of your widget
this.options.whatever;
},
答案 4 :(得分:0)
定义 var scope = this ,并在事件处理程序中使用 scope 。
_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);
});
},
答案 5 :(得分:0)
在不使用闭包的情况下执行相同操作的另一种方法是将窗口小部件作为事件数据的一部分传递,如下所示:
// 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);
};