2009-08-05 6 views
2

Ich habe diesen Code:Delegierung von Methoden in Javascript/jQuery?

var myWidget = $('#myWidget'); 

und ruft wie dies an anderer Stelle:

myWidget.hide(); 
myWidget.slideToggle(); 

Diese arbeiten natürlich, weil jQuery diese Methoden hinzufügt.

Nun lassen Sie sich sagen, ich bin etwas Refactoring tun mywidget ein richtiges Objekt mit seinen eigenen benutzerdefinierten Methoden und Staat zu machen:

var myWidget = (function() { 
    // private stuff 
    var actualJQueryObject = $('#myWidget'); 
    return { 
     publicMethod: function() {...}, 
     // MAGIC! 
    } 
})() 

aber ich möchte alle Anrufe haben, die ein jQuery-Objekt erwarten, die sind alle um meinen Code, um noch arbeiten, obwohl myWidget ist nicht mehr ein jQuery-Objekt, weil myWidget weiß, wie diese Aufrufe an actualJQueryObject zu delegieren.

Ist das möglich?

Antwort

3

Sie könnten auch extend Ihr jQuery-Objekt mit einem anderen Objekt, das Ihre benutzerdefinierten Methoden hat:

var myWidget = function() { 
    // private stuff 
    var actualJQueryObject = $('#myWidget'); 

    var extensionMethods = { 
     publicMethod: function() { alert('public method!'); } 
    } 
    return $.extend(actualJQueryObject, extensionMethods); 
}(); 

Nur vorsichtig sein mit dem Namen Ihrer Erweiterungsmethoden, um nicht mit anderen zu kollidieren jQuery definierte Funktion.

Sie können das obige Snippet here versuchen.

+0

Schön, danke. Ich wusste, dass es eine sehr einfache Art und Weise geben musste, um mit Erbschaft das zu tun, was ich wollte. – lawrence

+0

Überprüfen Sie meine Funktion, die unten aufgeführt ist, nur für den Fall, dass Sie mehrere Namespaces benötigen. – Tres

+0

Vielleicht möchten die Leute an dieser Stelle aber anfangen, jQuery() zu betrachten, die in 1.5 herauskam. – Quickredfox

1

Eine Option verwendet das ursprüngliche jquery-Objekt als Prototyp.

function wrap(jqObject) { 
    function MyNewType() { 
     this.changeFontSize = function(a) { 
      this.css({fontSize : this.size}); 
     }; 
    } 
    MyNewType.prototype = jqObject; 
    return new MyNewType; 
} 
var obj = wrap($('#someitem')); 
obj.size = 50;  // obj.size 
obj.changeFontSize(); // obj.changeFontSize 
obj.hide();   // $.hide 
obj.fadeIn("slow"); // $.fadeIn 
+0

Sehr schöne Antwort; Ich werde es benutzen. Gibt es eine Möglichkeit, die Erstellung wie normale Objektkonstruktion aussehen zu lassen, d. H. "Var obj = new Wrapper ($ ('# someitem'));" anstelle von "var obj = wrap ($ ('# someitem'));"? Es wäre auch hilfreich, zu zeigen, wie eine Wrapper-Methode hinzugefügt wird, die eine zugrunde liegende Methode desselben Namens umschließt, z. obj.fadeOut ("slow") ruft obj.fadeOut auf, was etwas zur Konsole ausgibt und dann $ .fadeOut aufruft. –

0

Ich habe ein Plugin geschrieben, das Ihnen helfen könnte. Es ist im Grunde ein Plugin zum Schreiben von Plugins. Diese Entwickler Gruppe Post erklärt es und hat einige Code-Beispiele:

http://groups.google.com/group/jquery-dev/browse_thread/thread/664cb89b43ccb92c/72cf730045d4333a?hl=en&q=structure+plugin+authoring#72cf730045d4333a

Und die Quelle hier:

http://code.google.com/p/jquery-plugin-dev/source/browse/trunk/jquery.plugin.js

EDIT:

ich eine Funktion erstellt, die hat ähnliche Funktionalität wie das Plugin:

jQuerify = function(fn) { 
    function plugin() { 
     var instantiate = false; 

     // check to see if it has any prototyped methods (we only need one iteration to do this) 
     for (var i in construct.prototype) { 
      instantiate = true; 

      break; 
     } 

     // if there are prototyped methods, return an instance (since an instance's return value won't vary) 
     // otherwise just call it using apply so the return value can vary 
     return instantiate 
      ? new construct(this, arguments) 
      : construct(this, arguments); 
    } 

    function construct(parent, args) { 
     // 'this' will not mimic jQuery unless given the length property 
     this.length = 0; 
     this.selector = parent.selector; 
     this.context = parent.context; 

     // mimic 'this' in jQuery, but for the plugin namespace 
     Array.prototype.push.apply(this, $.makeArray(parent)); 

     // return the constructors return value 
     // should be 'this' if you want to chain the new namespace 
     return fn.apply(this, arguments); 
    } 

    // copy all static properties and methods 
    for (var i in fn) { 
     plugin[i] = fn[i]; 
    } 

    // allow .fn and copy all instance properties and methods; the last part is for IE 
    plugin.fn = construct.prototype = plugin.prototype = fn.prototype; 

    return plugin; 
} 

Auf diese Weise können Sie benutzerdefinierte Objekte zu jQuery als Plugin hinzufügen, während ‚dies‘ mit auf die ausgewählten Objekte zu finden und erlaubt Ihnen auch eine unbegrenzte Tiefe zu Ihrem Namensraum haben:

function test1() { 
    return this; 
} 
test1.prototype.getHtml1 = function() { 
    return $(this).html(); 
} 

function test2() { 
    return this; 
} 
test2.prototype.getHtml2 = function() { 
    return $(this).html(); 
} 

function test3() { 
    return this; 
} 
test3.prototype.getHtml3 = function() { 
    return $(this).html(); 
} 

jQuery.fn.test1     = jQuerify(test1); 
jQuery.fn.test1.fn.test2   = jQuerify(test2); 
jQuery.fn.test1.fn.test2.fn.test3 = jQuerify(test3); 

jQuery(function($) { 

    alert($('body').test1().getHtml1()); 
    alert($('body').test1().test2().getHtml2()); 
    alert($('body').test1().test2().test3().getHtml3()); 

}); 
Verwandte Themen