如果我想调整jQuery UI对象的一些功能,通过替换其中一个函数,我将如何去做?
示例:假设我想修改jQuery自动完成小部件呈现建议的方式。自动完成对象上有一个方法如下:
_renderItem: function( ul, item) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
},
我可以替换它吗?
我认为这可能被称为 Monkey Patching 。
如何?我会使用什么语法?
答案 0 :(得分:18)
我不了解jQuery UI,但总的来说,这就是重新定义函数的方法:
(function() {
var _oldFunc = _renderItem;
_renderItem = function(ul,item) {
// do your thing
// and optionally call the original function:
return _oldFunc(ul,item);
}
})();
这包含在匿名函数中的原因是创建一个用于存储原始函数的闭包。这样它就不会干扰全局变量。
修改强>
要在jQuery UI小部件上对fn执行此操作,请使用以下语法:
仅供参考:获取该功能的方法如下:
function monkeyPatchAutocomplete() {
// don't really need this, but in case I did, I could store it and chain
var oldFn = $.ui.autocomplete.prototype._renderItem;
$.ui.autocomplete.prototype._renderItem = function( ul, item) {
// whatever
};
}
答案 1 :(得分:0)
我知道这是一个老问题,但我只需修复一个旧项目的一些错误,并且遇到了这种补丁的问题。
最好通过options对象使函数可用, 然后把你的具体逻辑放在那里。
(function monkeyPatchJQueryAutocomplete($) {
/**
* Proxies a private
* prototype method to the
* options Object
*
* @param {Object} obj
* @param {String} funcName
*/
function proxyPrivateMethodToOptions(obj, funcName) {
var __super = obj.prototype[funcName];
obj.prototype[funcName] = function() {
if (this.options[funcName]) {
return this.options[funcName].apply(this, arguments);
}
return __super.apply(this, arguments);
};
}
// Make the private _renderItem
// method available through the options Object
proxyPrivateMethodToOptions($.ui.autocomplete, '_renderItem');
// We can do this for other methods as well:
proxyPrivateMethodToOptions($.ui.autocomplete, '_renderMenu');
}($));
$('.some-input').autocomplete({
_renderItem: function(ul, item) {
console.log('here we can reference the old func via: ', __super);
return $("<li>")
.append($("<a>").text(item.label))
.appendTo(ul);
}
});