2009-08-02 18 views
8

Sto creando un plug-in jQuery di dimensioni piuttosto grandi. Infatti, il plugin è tecnicamente composto da alcuni plugin che funzionano tutti insieme.jQuery Plugin Namespacing Functions

(function($){ 
    $.fn.foo = function(){ 
     //plugin part A 
    } 
    $.fn.bar = function(){ 
     //plugin part B 
    } 
    $.fn.baz = function(){ 
     //plugin part C 
    } 
}(jQuery)) 

E 'possibile namespace plugin jQuery in modo tale che i plugin minori potrebbero essere le funzioni del plugin grande

$.fn.foo.bar = function(){} 
$.fn.foo.baz = funciton(){} 

Questo avrebbe impedito di inquinare la funzione dello spazio dei nomi di jQuery. È quindi possibile chiamare i plugin come

$('#example').foo() 
$('#other_example').foo.bar() 

Il problema che ho incontrato quando si cerca questo fuori me stesso è che le funzioni dichiarate come proprietà della funzione plug-foo() non hanno i loro riferimenti a 'questo' impostare correttamente. 'this' si riferisce all'oggetto padre e non all'oggetto jQuery.

Qualsiasi idea o opinione sarebbe apprezzata.

-Matt

risposta

11

Non appena si utilizza $.fn.foo.bar() - this punti $.fn.foo, che è quello che ci si aspetterebbe in JavaScript (this essendo l'oggetto che la funzione è chiamata.)

ho notato nel plugin di jQuery UI (come ordinabile) in cui si chiamano funzioni come:

$(...).sortable("serialize"); 
$(...).sortable({options}); 

se si stesse facendo qualcosa di simile - si potrebbe estendere j Query stessa:

$.foo_plugin = { 
    bar: function() {}, 
    baz: function() {} 
} 

$.fn.foo = function(opts) { 
    if (opts == 'bar') return $.foo_plugin.bar.call(this); 
    if (opts == 'baz') return $.foo_plugin.baz.call(this); 
} 
+0

Non avevo mai guardato prima la libreria dell'interfaccia utente jQuery. Ma questa è una soluzione molto interessante e applicabile. Grazie. – mazniak

1

Beh, sono sicuro che ci sono molti modi per la pelle questo gatto. La libreria jQuery UI utilizza un modello come questo:

// initialize a dialog window from an element: 
$('#selector').dialog({}); 

// call the show method of a dialog: 
$('#selector').dialog('show'); 
+1

Personalmente, credo questo modo di essere un trucco "sporco" a causa del fatto che non potevano usare $ ('# selector'). dialog(). show(), ma è un modo alternativo per farlo. – Tres

2

So che questo è già stato risposto, ma ho creato un plugin che fa esattamente ciò che si vuole:

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

ho incluso un piccolo esempio di sotto, ma di controllo questo post jQuery Dev Group per un esempio più approfondita: si http://groups.google.com/group/jquery-dev/browse_thread/thread/664cb89b43ccb92c/72cf730045d4333a?hl=en&q=structure+plugin+authoring#72cf730045d4333a

permette di creare un oggetto con il maggior numero di metodi come si desidera:

var _myPlugin = function() { 
    // return the plugin namespace 
    return this; 
} 

_myPlugin.prototype.alertHtml = function() { 
    // use this the same way you would with jQuery 
    alert($(this).html()); 
} 

$.fn.plugin.add('myPlugin', _myPlugin); 

ora si può andare:

$(someElement).myPlugin().alertHtml(); 

Ci sono, naturalmente, molte, molte altre possibilità con questo, come spiegato nel post gruppo dev.

0

Sono un fan del pattern che ho visto su Eric Martin SimpleModal. Funziona bene quando NON sto agendo su elementi DOM - in questo caso un wrapper per utilizzare localStorage.

In questo modo posso facilmente fare riferimento al costruttore:

$.totalStorage('robo', 'cop'); 

... o un metodo pubblico:

$.totalStorage.getItem('robo'); //returns 'cop' 

Ecco gli interni:

;(function($){ 

/* Variables I'll need throghout */ 

var ls; 
var supported = true; 
if (typeof localStorage == 'undefined' || typeof JSON == 'undefined') { 
    supported = false; 
} else { 
    ls = localStorage; 
} 

/* Make the methods public */ 

$.totalStorage = function(key, value, options){ 
    return $.totalStorage.impl.init(key, value); 
} 

$.totalStorage.setItem = function(key, value){ 
    return $.totalStorage.impl.setItem(key, value); 
} 

$.totalStorage.getItem = function(key){ 
    return $.totalStorage.impl.getItem(key); 
} 

/* Object to hold all methods: public and private */ 

$.totalStorage.impl = { 

    init: function(key, value){ 
     if (typeof value != 'undefined') { 
      return this.setItem(name, value); 
     } else { 
      return this.getItem(name); 
     } 
    }, 

    setItem: function(key, value){ 
     if (!supported){ 
      $.cookie(key, value); 
      return true; 
     } 
     ls.setItem(key, JSON.stringify(value)); 
     return true; 
    }, 

    getItem: function(key){ 
     if (!supported){ 
      return this.parseResult($.cookie(key)); 
     } 
     return this.parseResult(ls.getItem(key)); 
    }, 

    parseResult: function(res){ 
     var ret; 
     try { 
      ret = JSON.parse(res); 
      if (ret == 'true'){ 
       ret = true; 
      } 
      if (ret == 'false'){ 
       ret = false; 
      } 
      if (parseFloat(ret) == ret){ 
       ret = parseFloat(ret); 
      } 
     } catch(e){} 
     return ret; 
    } 
}})(jQuery);