Letztendlich gibt es mehrere Möglichkeiten vorhandene jQuery UI Widgets zu erweitern. Die hierzu am häufigsten verwendete Methode ist die $.extend. Was in etwa so aussieht:
//neues a11yTabs erweitert tabs
$.widget('ui.a11yTabs', $.extend({}, $.ui.tabs.prototype, {
select: function(){
$.ui.tabs.prototype.select.apply(this, arguments);
}
});
// tabs selbst erweitern
//altes select sichern
var oldSelect = $.ui.tabs.prototype.select;
$.extend($.ui.tabs.prototype, {
select: function(){
oldSelect.apply(this, arguments);
}
});
Überschreibt man hierdurch eine bereits vorhandene Funktion, welche man noch nutzen möchte, muß man diese, wie im zweiten Beispiel geschehen, vor dem überschreiben zwischenspeichern, so daß man weiterhin auf die Originalmethode Zugriff hat.
Eine relativ elegante Schreibweise hierzu findet sich bei Felix Nagel, welcher folgenden einfachen Code zeigt:
// extends original ui.tabs widget
$.extend($.ui.tabs.prototype,{
// copy original method
_original_init: $.ui.tabs.prototype._init,
// when widget is initiated
_init: function() {
var self = this, options = this.options;
// fire original method
self._original_init();
// now we can do some accessibility stuff
}
});
Wenn man derartiges drei- bis viermal schreiben muß, kommt man sich aber doch recht schnell etwas blöd vor. Als sich mir eben dieses Problem stellte, hatte ich daher folgende kleine extend-Methode geschrieben (noch nicht völlig durchgetestet):
var slice = Array.prototype.slice;
$.widgetExtend = function(widget, exts){
var args = arguments;
$.each(exts, function(name, fn){
if( name in widget ){
if( fn && $.isFunction(fn) ){
fn._super = widget[name];
} else {
widget['_super'+ name] = widget[name];
}
}
widget[name] = fn;
});
if( args.length > 2 ){
args = slice.call(arguments, 2);
args.unshift(widget);
widget = $.widgetExtend.apply(this, args);
}
return widget;
};
Mit dieser kleinen Methode kann man, dannn ohne lästiges zwischenspeichern über arguments.callee._super auf die Hauptmethode zugreifen:
//neues a11yTabs erweitert tabs
$.widget('ui.a11yTabs', $.widgetExtend({}, $.ui.tabs.prototype, {
select: function(){
//$.ui.tabs.prototype.select kann eigentlich auch noch verwendet werden
arguments.callee._super.apply(this, arguments);
}
});
// tabs selbst erweitern
$.widgetExtend($.ui.tabs.prototype, {
select: function(){
arguments.callee._super.apply(this, arguments);
}
});
Super snippet! Vielen, vielen Dank
Nur als kleine Frage: Kommt man irgendwie um arguments.callee herum, da deprecated?
grüße
Comment by Basti — June 29, 2010 @ 1:52 pm
ja, klar. arguments.callee zeigt ja immer auf die aufgerufene function, du kannst das _super in dem beispiel oben auf über this.select._super erreichen.
Für das vererben haben die leute von jQuery UI übrigens in der aktuellen Version ein tolles Feature eingebaut. (Beispiel: a11yTabs erbt von tabs), welches man auch nutzen kann/sollte.
Ich werde, wenn ich ein bißchen Zeit habe mal darüber schreiben.
Grüße
Alex
Comment by alexander farkas — June 29, 2010 @ 8:03 pm
Oh stimmt. Dumme Frage
Danke für die Hinweise, dann schau ich mir mal die Vererbung in der aktuellen 1.8er an.
super Beiträge, weiter so!
Comment by Basti — June 30, 2010 @ 4:57 pm