¿Puedo sustituir o modificar una función en un widget de jQuery UI? ¿Cómo? (Monkey Patching)

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

  •  19-09-2019
  •  | 
  •  

Pregunta

Si quiero modificar algo de la capacidad de un objeto jQuery UI, mediante la sustitución de una de las funciones, ¿cómo voy a ir haciendo eso?

Ejemplo: supongamos que se quiere modificar la forma en que el widget de autocompletar jQuery rindió las sugerencias. Hay un método en el objeto de autocompletar que tiene este aspecto:

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

¿Puedo reemplazar esto?

Creo que esto podría ser llamado Mono Parches .

¿Cómo? Lo que debería utilizar la sintaxis?

¿Fue útil?

Solución

No sé acerca de jQuery UI, pero en general, así es como se redefine una función:

(function() {
   var _oldFunc = _renderItem;

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

La razón de esto está envuelto en una función anónima es crear un cierre para el almacenamiento de la función original. De esta manera nunca puede interferir con las variables globales.


Editar
Para hacer esto a un fn en un widget de jQuery UI, utilice la siguiente sintaxis:

Para su información: la manera de captar la función es la siguiente:

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

Otros consejos

Sé que es una vieja pregunta, pero yo sólo tenía que corregir algunos errores en un viejo proyecto y tenía un problema con este tipo de parche.

Es mejor hacer la función disponible a través de las opciones del objeto, y luego poner su lógica específica allí.

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

}($));

Uso-ejemplo:

$('.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);
  }
});
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top