Can I replace or modify a function on a jQuery UI widget? How? (Monkey Patching)

為{幸葍}努か 提交于 2019-12-18 13:09:10

问题


If I want to tweak some of the capability of a jQuery UI object, by replacing one of the functions, how would I go about doing that?

Example: suppose I wanted to modify the way the jQuery autocomplete widget rendered the suggestions. There's a method on the autocomplete object that looks like this:

_renderItem: function( ul, item) {
    return $( "<li></li>" )
        .data( "item.autocomplete", item )
        .append( "<a>" + item.label + "</a>" )
        .appendTo( ul );
},

Could I replace this?

I think this might be called Monkey Patching.

How? What syntax would I use?


回答1:


I don't know about jQuery UI, but in general, this is how you redefine a function:

(function() {
   var _oldFunc = _renderItem;

   _renderItem = function(ul,item) {
      // do your thing
      // and optionally call the original function:
      return _oldFunc(ul,item);
   }
})();

The reason this is wrapped in an anonymous function is to create a closure for storing the original function. This way it can never interfere with global variables.


EDIT
To do this to a fn on a jQuery UI widget, use this syntax:

FYI: the way to grab the function is like this:

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
  }; 
} 



回答2:


I know it's an old question, but I just had to fix some bugs on an old project and had an issue with this kind of patch.

Better make the function available through the options object, and then put your specific logic there.

Patch:

(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');

}($));

Usage-Example:

$('.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);
  }
});


来源:https://stackoverflow.com/questions/2436315/can-i-replace-or-modify-a-function-on-a-jquery-ui-widget-how-monkey-patching

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!