2010-03-26 11 views
30

Vorrei creare una versione personalizzata del widget ordinabile. Ho cercato la documentazione, ma non ho trovato nulla di veramente accurato. Le migliori informazioni che ho trovato sono state: http://jqueryui.pbworks.com/Widget-factory.Come estendere un widget ui jquery? (1.7)

ho provato:

$.widget("ui.customsortable", $.extend($.ui.sortable, { 
    _init: function() { 
    $.widget.prototype._init.apply(this, arguments); 
    } 
})); 

Ma $ .widget.prototype._init non è la funzione che voglio chiamare Credo che dal momento che è il prototipo $ .widget.

Poi, ho provato qualcosa che ho letto qua e là:

var _init = $.ui.sortable.prototype._init; 

$.widget("ui.customsortable", $.extend($.ui.sortable, { 
    _init: function() { 
    _init.apply(this, arguments); 
    }, 
})); 

Ma:

  • Non posso credere che devo memorizzare tutti i metodi che voglio ignorare come questo, è così brutto.
  • Si genera un errore ("This.Refresh non è una funzione"), che significa che il metodo di aggiornamento non esiste. Ciò significa che dovrei ricreare tutti i metodi che voglio scavalcare? Che senso ha estendere in quel caso?

mi manca qualcosa qui?

Grazie per il vostro aiuto!

+1

In 1.8 questo è molto facile. – PetersenDidIt

+2

Com'è facile in 1.8? – powtac

+3

In 1.8, la funzione $ .widget() accetta un widget di base come secondo parametro. http://docs.jquery.com/UI_Developer_Guide#The_widget_factory – itsadok

risposta

22

Dopo diversi tentativi, ho finalmente trovato il modo di farlo facilmente:

$.widget("ui.customsortable", $.extend({}, $.ui.sortable.prototype, { 

    _init: function(){ 
    this.element.data('sortable', this.element.data('customsortable')); 
    return $.ui.sortable.prototype._init.apply(this, arguments); 
    } 

    // Override other methods here. 

})); 

$.ui.customsortable.defaults = $.extend({}, $.ui.sortable.defaults); 

La chiave è quella di copiare i dati dalla widget personalizzato a quello originale. Non dimenticare di usare $ .ui.sortable.prototype [metodo sovrascritto] .Applicare (questo, argomenti).; in ogni metodo sovrascritto.

Agrifoglio merda!

+9

Questo è molto sbagliato. Vedi la risposta di Bullgare sotto. –

2

Non so proprio quello che stai dopo, quando si dice "estendere un widget". Nel mio caso volevo cambiare il modo in cui il widget si rendeva, e giocherellare con le classi CSS non soddisfaceva. Non si trattava di estendere il comportamento di un widget, ma piuttosto di modificare il comportamento di un widget.

Così ho over-rode il metodo di rendering. Il widget in questione era the jQueryUI autocomplete, e l'over-ride si presentava così:

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

Ho appena chiamato che nel $(document).ready().


correlato:
- Can I replace or modify a function on a jQuery UI widget? How?
- jQueryUI: how can I custom-format the Autocomplete plug-in results?

+0

Grazie per la risposta. Sfortunatamente, non voglio modificare il widget esistente, dal momento che voglio che il widget originale rimanga intatto. Un altro modo per ottenere quello che fai sarebbe: $ .extend ($. Ui.sortable.prototype, {...}); Voglio creare un nuovo widget basato su uno esistente, con ereditarietà, nella logica della programmazione OO. – Jide

+0

Credo che dovremmo piuttosto memorizzare la vecchia funzione nello stesso spazio dei nomi: '$ .ui.autocomplete.prototype._originalRenderItem = $ .ui.autocomplete.prototype._renderItem;'. – jjmontes

3

Per quanto riguarda la soluzione scelta in precedenza:

$.widget("ui.customsortable", $.extend(true, {}, $.ui.sortable.prototype, { 

Se si estende uno oggetti opzioni in un altro, il [profondo] bandiera del vero vi darà i risultati desiderati.

2

Ho usato questa volta:

$.ui.buttonset.prototype.value = function() { 
    return this.element.find('#' + this.element.find('label[aria-pressed="true"]').attr('for')).val(); 
} 
28

Queste sono le risposte un po 'strano. Esiste un secondo parametro opzionale: basewidget da cui ereditare. È facile. Non c'è bisogno di lavorare con il prototipo e così via.

$.widget("ui.customsortable", $.ui.sortable, { 

    _init: function() { 
    this.element.data('sortable', this.element.data('customsortable')); 
    // or whatever you want 
    } 
}); 

Il secondo parametro è $ .ui.sortable. Penso che sia tutto ciò di cui hai bisogno.

3

Sto usando questo al fine di predefinire avvio, arresto e l'aggiornamento funzioni:

$.widget('ui.custom_sortable_or_any_other_name', $.ui.sortable, { 
    _init: function() { 
     this.element.children().css('position', 'relative'); //for example 
    }, 
    options : { 
     start: function (event, ui) { 
      ui.item.addClass('noclick'); //ui.item get's the item, that's my point 
     }, 
     stop: function (event, ui) {    
     }, 
     update: function (event, ui) { 
      $.ajax(); //some ajax you might want to do 
     } 
    } 
}); 
Problemi correlati