jQuery UI Extender widgets mediante el Widget Factory

El Widget Factory de jQuery UI facilita la creación de widgets que extienden la funcionalidad de los widgets existentes. De esta manera, puede crear widgets potentes sobre la base existente, o realizar ajustes sutiles en la funcionalidad de los widgets existentes.

Nota:Antes de estudiar este capítulo, debe comprender qué es el Widget Factory y cómo funciona. Si no está familiarizado con estos conocimientos, consulte primeroCómo utilizar el Widget Factoryel capítulo.

Crear extensiones de widgets

La creación de widgets mediante el Widget Factory se realiza pasando a$.widget()el nombre del widget y un objeto prototipo. El siguiente ejemplo crea un widget "superDialog" en el espacio de nombres "custom".

$.widget( "custom.superDialog", {} );

Para admitir la extensión,$.widget()acepta opcionalmente el constructor del widget que se usará como widget padre. Cuando se especifica un widget padre, pásalo como segundo parámetro, después del nombre del widget y antes del objeto prototipo del widget.

Al igual que en el ejemplo anterior, a continuación también se creará un widget "superDialog" en el espacio de nombres "custom". Pero esta vez se pasael widget dialog (diálogo) de jQuery UIsu constructor ($.ui.dialog), lo que indica que el widget superDialog debe usar el widget dialog (diálogo) de jQuery UI como widget padre.

$.widget( "custom.superDialog", $.ui.dialog, {} );

Aquí, los widgets superDialog y dialog son esencialmente equivalentes, solo difieren en nombre y espacio de nombres. Para que nuestro nuevo widget tenga más características, podemos añadir algunos métodos a su objeto prototipo.

El objeto prototipo del widget se pasa como$.widget()el último parámetro.

$.widget( "custom.superDialog", $.ui.dialog, {
    red: function() {
        this.element.css( "color", "red" );
    }
});
 
// Create a new <div>, convert it into a superDialog, and call the red() method.
$( "<div>I am red</div>" )
    .superDialog()
    .superDialog( "red" );

AhorasuperDialogtiene unred()método, que cambiará su color de texto a rojo. Observe cómo el Widget Factory establece automáticamentethiscomo la instancia del widget. Para conocer la lista de todos los métodos y propiedades disponibles en la instancia, visitela documentación de la API del Widget Factory。

Extender métodos existentes

A veces, necesita ajustar o agregar el comportamiento de los métodos de un widget existente. Puede especificar el nombre del método como el nombre del método que se va a sobrescribir en el objeto prototipo. El siguiente ejemplo sobrescribe elopen()método de dialog (diálogo).. Como el diálogo está abierto de forma predeterminada, al ejecutar este código,"open"se registrará.

$.widget( "custom.superDialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
    }
});
 
// Create a new <div>, and convert it into a superDialog.
$( "<div>" ).superDialog();

Al ejecutar este código, hay un problema. Como hemos sobrescritoopen()el comportamiento predeterminado, el dialog (diálogo) ya no se muestra en la pantalla.

Cuando usamos un método en el objeto prototipo, en realidad estamos sobrescribiendo el método original, usando un nuevo método en la cadena de prototipos.

Para que los métodos del widget padre estén disponibles, el Widget Factory proporciona dos métodos:_super()y_superApply()。

Usar_super()y_superApply()para acceder al widget padre

_super()y_superApply()Llama al mismo método en el widget padre. Vea el siguiente ejemplo. Al igual que el ejemplo anterior, este ejemplo también sobrescribeopen()el método para registrar"open". Sin embargo, esta vez ejecutar_super()es llamar al método de dialog (diálogo)open(), y abre el diálogo.

$.widget( "custom.superDialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
 
        // Invoke the parent widget's open().
        return this._super();
    }
});
 
$( "<div>" ).superDialog();

_super()y_superApply()En realidad es equivalente alFunction.prototype.call()yFunction.prototype.apply()método original. Por lo tanto,_super()acepta una lista de argumentos,_superApply()acepta un array como parámetro. El siguiente ejemplo demuestra la diferencia entre ambos.

$.widget( "custom.superDialog", $.ui.dialog, {
    _setOption: function( key, value ) {
 
        // Both invoke dialog's setOption() method. _super() requires the arguments
        // be passed as an argument list, _superApply() as a single array.
        this._super( key, value );
        this._superApply( arguments );
    }
});

Redefinir widgets

jQuery UI 1.9 añadió la funcionalidad de redefinir widgets. Por lo tanto, sin necesidad de crear un nuevo widget, solo necesitamos pasar$.widget()el nombre y el constructor de un widget existente. El siguiente ejemploopen()añade el mismo registro, pero no se hace creando un nuevo widget.

$.widget( "ui.dialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
        return this._super();
    }
});
 
$( "<div>" ).dialog();

Con este método, podemos extender un método de un widget existente, pero aún podemos usar_super()para acceder al método original: nada de esto se hace creando un nuevo widget, sino redefiniendo directamente el widget.

Widgets y polimorfismo

Al interactuar entre las extensiones de widgets y sus plugins, hay un punto que vale la pena destacar: el plugin del widget padre no se puede usar para llamar a métodos en los elementos del widget hijo. El siguiente ejemplo demuestra esto.

$.widget( "custom.superDialog", $.ui.dialog, {} );
 
var dialog = $( "<div>" ).superDialog();
 
// This works.
dialog.superDialog( "close" );
 
// This doesn't.
dialog.dialog( "close" );

En el ejemplo anterior, el plugin del widget padre,dialog(), no puede llamar alclose()método en el elemento superDialog. Para obtener más información sobre cómo llamar a métodos de widgets, consulteLlamadas a métodos de widgets。

Personalizar instancias individuales

Hasta ahora, los ejemplos que hemos visto tienen métodos extendidos en el prototipo del widget. Sobrescribir métodos en el prototipo afecta a todas las instancias del widget.

Para demostrar esto, vea el siguiente ejemplo. Las dos instancias de dialog (diálogo) utilizan el mismoopen()método.

$.widget( "ui.dialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
        return this._super();
    }
});
 
// Create two dialogs, both use the same open(), therefore "open" is logged twice.
$( "<div>" ).dialog();
$( "<div>" ).dialog();

A veces, solo necesita cambiar el comportamiento de una instancia particular del widget. Para ello, debe usar la asignación normal de propiedades de JavaScript, obtener una referencia a la instancia y sobrescribir el método. Como se muestra en el siguiente ejemplo.

var dialogInstance = $( "<div>" )
    .dialog()
    // Retrieve the dialog's instance and store it.
    .data( "ui-dialog" );
 
// Override the close() method for this dialog
dialogInstance.close = function() {
    console.log( "close" );
};
 
// Create a second dialog
$( "<div>" ).dialog();
 
// Select both dialogs and call close() on each of them.
// "close" will only be logged once.
$( ":data(ui-dialog)" ).dialog( "close" );

La técnica de sobrescribir métodos en una instancia personalizada es una personalización única perfecta.

Otras extensiones