Posso sostituire o modificare una funzione su un widget jQuery UI? Come? (Scimmia Patching)

StackOverflow https://stackoverflow.com/questions/2436315

  •  19-09-2019
  •  | 
  •  

Domanda

Se voglio modificare alcune delle capacità di un oggetto jQuery UI, sostituendo una delle funzioni, come dovrei andare a fare che?

Esempio: supponiamo che io volevo modificare il modo in cui il widget di jQuery autocomplete reso i suggerimenti. C'è un metodo sull'oggetto di completamento automatico che assomiglia a questo:

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

Potrei sostituire questo?

Credo che questo potrebbe essere chiamato Scimmia Patching .

Come? Cosa sintassi dovrei usare?

È stato utile?

Soluzione

Non so su jQuery UI, ma in generale, questo è il modo per ridefinire una funzione:

(function() {
   var _oldFunc = _renderItem;

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

Il motivo di questo è avvolto in una funzione anonima è quello di creare una chiusura per memorizzare la funzione originale. In questo modo non può mai interferire con le variabili globali.


Modifica
Per fare questo ad un fn su un widget di jQuery UI, utilizzare la seguente sintassi:

A proposito: il modo per afferrare la funzione è simile a questo:

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

Altri suggerimenti

Lo so che è una vecchia questione, ma ho dovuto correggere alcuni bug su un vecchio progetto e ha avuto un problema con questo tipo di patch.

Meglio fare la funzione disponibile attraverso le opzioni oggetto, e poi mettere la logica specifica lì.

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

}($));

Utilizzo-Esempio:

$('.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);
  }
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top