2010-10-12 19 views
9

Ho sviluppato un piccolo widget javscript per trasformare alcuni blocchi nidificati <ul> in un browser in stile Windows Explorer. Di recente ho imparato a conoscere il modello letterale oggetto e ha deciso di dare un andare, così l'organizzazione del mio codice è qualcosa di simile:modello letterale di oggetti javascript con più istanze

var myExplorer = { 
    init : function(settings) { 
     myExplorer.config = { 
      $wrapper : $('#explorerCategories'), 
      $contentHolder : $j('#categoryContent'), 
      loadingImg : '<img src="../images/standard/misc/ajax_loader.gif" alt="loading" class="loading" />' 
     } 
     // provide for custom configuration via init() 
     if (settings && typeof(settings) == 'object') { 
      $.extend(myExplorer.config, settings); 
     } 

     // some more code... 
    }, 

    createExpanderLink : function() { 
     // more code 
    }, 

    anotherMethod : function() { 
     // etc 
    } 
} 

Poi nella mia pagina ho impostato il mio Explorer con:

$j(function() { 
    myExplorer.init(); 
} 

Tutto questo va bene comunque. Il problema è quando voglio avere più di uno di questi widget di stile Explorer sulla stessa pagina. Ho provato a passare nelle diverse impostazioni:

$j(function() { 
    // first instance 
    myExplorer.init(); 

    //second instance 
    var settings = { 
     $wrapper : $('#explorerCategories2'), 
     $contentHolder : $j('#categoryContent2') 
    } 
    myExplorer.init(settings); 

} 

Ma questo sovrascrive semplicemente le valli di configurazione per la prima istanza che rompe efficacemente. Sto iniziando a rendermi conto che il modello letterale dell'oggetto non è la strada da percorrere qui, ma non sono sicuro di cosa sia. Qualcuno può offrire qualche suggerimento?

risposta

9

Utilizzare invece una funzione su un oggetto letterale, in modo da poter istanziare più oggetti del widget utilizzando la parola chiave new.

function myExplorer(settings) { 
    // init code here, this refers to the current object 
    // we're not using a global object like myWindow anymore 
    this.config = { 
     $wrapper : $('#explorerCategories'), 
     $contentHolder : $j('#categoryContent'), 
     .. 
    }; 

    // provide for custom configuration 
    if (settings && typeof(settings) == 'object') { 
     $.extend(this.config, settings); 
    } 

    this.someFunction = function() { 
     .. 
    }; 

    this.otherFunction = function() { 

    }; 
} 

Instantate come molti oggetti di questo widget, se necessario utilizzando,

var foo = new myExplorer({ .. }); 
var bar = new myExplorer({ .. }); 
... 
+0

Perdona la mia ignoranza, ma è giusto che quando si utilizza questo modello, io debba dichiarare tutte le funzioni interne prima di utilizzarle nella funzione circostante myExplorer. Mi sono un po 'confuso dal tuo // codice di init qui comment. – benb

2

Quando si chiama $.extend() in questo modo, si fonde le proprietà del secondo oggetto nella prima:

$.extend(myExplorer.config, settings); 

Invece, creare un nuovo oggetto che è il risultato della fusione lasciando il primo oggetto (i valori di default) intatto, in questo modo:

this.settings = $.extend({}, myExplorer.config, settings); 

Quello che fa è ancora unire gli oggetti passati nel primo, ma il primo è un nuovo oggetto ({}), quindi non siamo interessano uno degli altri, quindi usa semplicemente this.settings (o un nome diverso per renderlo assolutamente chiaro) all'interno dell'oggetto.

+0

Grazie. Ho provato questo ma non ha funzionato per me. Durante la creazione di un nuovo oggetto delle impostazioni nell'oggetto myExplorer, i valori venivano comunque sovrascritti dalla seconda chiamata myExplorer.init (impostazioni). – benb

+0

@ben - Non stavo nemmeno guardando la struttura del tuo oggetto, hai solo un singolo oggetto, dovrai seguire un percorso completamente diverso per la creazione dell'oggetto usando il precedente, la risposta di Anurag è una possibilità, ci sono molti modelli Qui. –

8

Che dire di questo?

 
var myExplorer = function(settings) { 

    var o = { 
    init: function() { 
     this.somevalue = settings; 
    }, 

    whatever: function() { 
    } 
    }; 

    o.init(); 

    return o; 
}; 

var exp1 = myExplorer('something'); 
var exp2 = myExplorer('anything'); 

console.log(exp1.somevalue); //something 
console.log(exp2.somevalue); //anything 
4

utilizzare il seguente codice per ottenere questo, ricordare a proposito del 'API pubblica' (in modo che la funzione 'interno' sarà visibile 'al di fuori'):

var myExplorer = function() { 
    var init = function(settings) { 
     var config = { 
      $wrapper : $('#explorerCategories'), 
      $contentHolder : $j('#categoryContent'), 
      loadingImg : '<img src="../images/standard/misc/ajax_loader.gif" alt="loading" class="loading" />' 
     } 
     // provide for custom configuration via init() 
     if (settings && typeof(settings) == 'object') { 
      $.extend(config, settings); 
     } 

     // some more code... 
    }, 

    var createExpanderLink = function() { 
     // more code 
    }, 

    var anotherMethod = function() { 
     // etc 
    } 

    // Public API 
    // return the functions you want to use outside of the current instance 
    return { 
     init : init, 
     createExpanderLink : createExpanderLink, 
     anotherMethod : anotherMethod 
    } 
} 
var firstExplorer = new myExplorer(); 
var secondExplorer = new myExplorer(); 
// etc 
0

Dalla mia comprensione sei cercando di creare una nuova istanza di oggetto che è stata definita utilizzando la notazione letterale dell'oggetto. I valori letterali degli oggetti possono essere istanziati utilizzando il metodo Object.create. Ecco il codice che spiega come istanziare un oggetto dalla notazione letterale dell'oggetto.

  var objLiteral = { 
       name:"kanthan", 
       address:'', 
       deliver:function(){ 
        if(this.address){ 
         console.log("Your product has been successfully delivered at "+this.address); 
        } 
        else{ 
         console.log("please enter the address to deliver"); 
        } 
       } 
      }; 
      var cum=Object.create(objLiteral); 
      cum.address="gkm colony"; 
      objLiteral.deliver(); 
      cum.deliver(); 
      var cum1=objLiteral; 
      cum1.address="gkm colony"; 
      objLiteral.deliver(); 
      cum1.deliver(); 
Problemi correlati