2 Stimmen

Unterklassenbildung eines jQuery-Objekts

Ich möchte eine subclassed jQuery Wrapper, die alle Methoden jQuery hat plus einige mehr zu machen. Ich würde auch gerne einige jQuery-Methoden außer Kraft setzen. Hier ist ein Beispiel für das, was ich gerne erreichen würde

  calendar('.cal').showPopup()
                  .selectDate(new Date())
                  .addClass('popup-visible');
  alert(calendar.val());

Beachten Sie, dass der Kalender genauso funktioniert wie das jQuery-Objekt außer

  • Es hat einige zusätzliche Methoden (showPopup und selectDate)
  • Sie hat eine überschriebene Methode (val)
  • Bei Verwendung der Methodenverkettung wird das Kalenderobjekt zurückgegeben. Das bedeutet, dass addClass nicht auf ein jQuery-Objekt zurückgreifen sollte.

Ich wäre dankbar, wenn mir jemand die richtige Richtung weisen könnte. Ich habe mit Bereichen und $.extend und Prototypen gespielt, aber kann nicht scheinen, etwas zu bekommen, zu arbeiten.

Merci !

4voto

Venkat D. Punkte 2939

Es stellt sich heraus, dass jQuery 1.5 eine neue Methode namens sub hat :)

Der Dokumentation zufolge sind sub

erstellt eine neue Kopie von jQuery, deren Eigenschaften und Methoden geändert werden können, ohne das ursprüngliche jQuery-Objekt. http://api.jquery.com/jQuery.sub/

Diese Methode erlaubte es nicht, eine Unterklasse zu unterteilen, aber ich fand eine geänderte Methode in ihrem Ticket Tracker, die dies erlaubte:

jQuery.subclass = function(){
  function jQuerySubclass( selector, context ) {
    return new jQuerySubclass.fn.init( selector, context );
  }
  jQuery.extend(true, jQuerySubclass, this);
  jQuerySubclass.superclass = this;
  jQuerySubclass.fn = jQuerySubclass.prototype = this();
  jQuerySubclass.fn.constructor = jQuerySubclass;
  jQuerySubclass.fn.init = function init( selector, context ) {
    if (context && context instanceof jQuery && !(context instanceof jQuerySubclass)){
      context = jQuerySubclass(context);
    }
    return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
  };
  jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
  var rootjQuerySubclass = jQuerySubclass(document);
  return jQuerySubclass;
};

Damit können Sie etwa so vorgehen:

var Calendar = jQuery.subclass();
Calendar.create = function() {
  var cal = Calendar( /* some html code for building the calendar */ );

  // Do some processing like binding events, etc

  return cal;
}
Calendar.fn.val = function(value) {
  //Calendar's implementation of val
}

Das Calendar-Objekt verhält sich genau wie ein jQuery-Objekt außer für die oben genannten Unterschiede. Es wird auch korrekt eine Instanz von Calendar zurückgeben, wenn ich Methoden miteinander verkette. Das ist toll, weil

  • Wir können leicht benutzerdefinierte Widgets erstellen erstellen, ohne den jQuery Namespace.
  • Wir können unsere eigenen Implementierungen von jQuery-Methoden bereitstellen
  • Wir können die Leistungsfähigkeit von jQuery mit Methoden wie trigger und bind nutzen, die bereits Teil der Klasse sind

Als nächstes bin ich daran interessiert, dass Klassen per Selektor registriert werden können. Auf diese Weise, wenn Sie $('.MyAwesomeCalendar') aufrufen, erhalten Sie ein Kalender-Objekt zurück, ohne explizit Calendar('.MyAwesomeCalendar') aufrufen zu müssen.

1voto

philwinkle Punkte 6948

Ich beginne damit, dass ich denke, Sie sollten sich ein wenig mehr mit jQuery's $.fn Plugin-Methode. Sie können hier mehr darüber lesen:

http://docs.jquery.com/Plugins/Authoring

Ich würde die oben genannten Aufgaben folgendermaßen erledigen:

(function($){
  $.fn.calendar = function(){
    //do something useful
    return this; // necessary for chaining
  };
  $.fn.calendar.showPopup = function(){
    //do something useful
    return this; //necessary for chaining
  }
)(jQuery);

Das heißt also, dass. Ihr obiges Beispiel würde eine ähnliche Syntax erfordern, um jQuery an Ihre calendar Funktion, und diese muss die Calendar's this um eine Verkettung zu ermöglichen. Ich kann diesen Code unten nicht beweisen, aber es ist ein guter Anfang:

var Calendar = (function($){
  calendar = {
    showPopup : function($){
      //do something useful
      return $; //required for chaining
    },
    val : function($){
      //return your inherent functionality
      return $; //required for chaining
     }

  }  
});
var calendar = new Calendar(jQuery);

Wie ich schon sagte, es ist hässlich und überhaupt nicht so, wie es gemacht werden sollte.

Ich bin kein Javascript-Experte - aber ich glaube, so wird das gemacht. Ich freue mich auch über jede Kritik.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X