我有一个jQuery UI函数,在_create函数中我有var self = this
所以我可以从插件中的其他函数访问插件上下文。
我在_create函数中也有这个代码:
//setup sortable handler
if (self.options.sortable !== false) {
var soptions = {
items:'.tagit-choice',
containment:'parent',
start:function (event, ui) {
console.log('sorting started', event, ui);
self._sortable.tag = $(ui.item);
self._sortable.origIndex = self._sortable.tag.index();
},
update:function (event, ui) {
console.log('sorting started', event, ui);
self._sortable.newIndex = self._sortable.tag.index();
self._moveTag(self._sortable.origIndex, self._sortable.newIndex);
console.log('moved tag', self._sortable.origIndex, 'to', self._sortable.newIndex);
}
};
if (self.options.sortable == 'handle') {
$('.tagit-choice', this.element).prepend('<a class="ui-icon ui-icon-grip-dotted-vertical" style="float:left"></a>');
soptions.handle = 'a.ui-icon';
soptions.cursor = 'move';
}
self.element.sortable(soptions);
}
在插件中设置可排序。
我打电话给self._moveTag
,我在其中呼叫console.log(self)
,我希望self
成为插件实例,而不是DOMWindow
。这是为什么?
_moveTag: function (old_index, new_index) {
console.log(self);
self.tagsArray.splice(new_index, 0, self.tagsArray.splice(old_index, 1)[0]);
for (var ind in self.tagsArray)
self.tagsArray[ind].index = ind;
if(self.options.select){
$('option:eq(' + old_index + ')', this.select).insertBefore($('option:eq(' + new_index + ')', this.select));
}
},
<小时/> 希望这个例子更清楚:
(function($) {
$.widget("ui.widgetName", {
options: {
sortable: true
},
_sortable: {},
_create: function() {
var self = this;
if (self.options.sortable !== false) {
self.element.sortable({
items: '.tagit-choice',
containment: 'parent',
start: function(event, ui) {
self._sortable.tag = $(ui.item);
self._sortable.origIndex = self._sortable.tag.index();
},
update: function(event, ui) {
self._sortable.newIndex = self._sortable.tag.index();
self._moveTag(self._sortable.origIndex, self._sortable.newIndex);
}
});
}
},
_moveTag: function(old_index, new_index) {
console.log(self); // <-- this returns DOMWindow?!?!?
}
});
})(jQuery);
答案 0 :(得分:2)
为什么您希望self
内部_moveTag
定义self
?显然有人将window.self
泄露到self
,你正在_moveTag
内找到错误的self
,window
恰好是(function($) {
$.widget('ui.pancakes', {
_create: function() {
var self = this;
self._moveTag();
},
_moveTag: function() {
// ...
}
});
})(jQuery);
;给出这样的东西:
self
_create
内的self
是您希望self
成为的窗口小部件,但_moveTag
不在_moveTag
的范围内,window.self
从其他地方拿起泄露的self
。因此,您可以在_create
内使用_create
以及_moveTag
中定义的任何函数,并获得期望值;但_create
以通常的方式定义为窗口小部件方法(而不是self
的范围内),因此它会选择坏的外部self
,而window
是{ {1}}。
我认为您的隐私_moveTags
方法会导致self
滥用。您应该在widget方法中使用this
并确保调用者使用正确的上下文; jQuery-UI将为您调用具有正确上下文的公共方法,您应该能够自己轻松地处理私有方法(例如_moveTag
)。
以下是一个简单的演示示例:http://jsfiddle.net/ambiguous/UhE3F/
一个小小的调查揭示了一个令人震惊的事实:window
应该有一个self
property:
<强> window.self 强>
返回对窗口对象的对象引用。
并且事实证明var self = this
约定是有史以来最糟糕的想法之一,或者至少使用名称self
这是一个可怕的想法。这是一个令人困惑的错误来源。