2010-10-12 3 views
9

J'ai développé un petit widget javscript pour transformer certains blocs <ul> imbriqués dans un navigateur de style Windows Explorer. Je l'ai appris récemment sur l'objet modèle littéral et a décidé de lui donner un coup, si l'organisation de mon code est quelque chose comme ceci:javascript objet modèle littéral avec plusieurs instances

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 
    } 
} 

Puis dans ma page je configurer mon explorateur avec:

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

Tout cela fonctionne bien d'ailleurs. Le problème est quand je veux avoir plus d'un de ces widgets de style explorateur sur la même page. J'ai essayé de passer dans les différents paramètres:

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

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

} 

Mais simplement les écrasent Vales de configuration pour la première instance qui rompt efficacement. Je commence à réaliser que le modèle littéral d'objet n'est pas le chemin à parcourir ici mais je ne suis pas sûr de ce qui est. Quelqu'un peut-il offrir des pointeurs?

Répondre

9

Utilisez une fonction à la place sur un littéral d'objet, de sorte que vous puissiez instancier plusieurs objets du widget à l'aide du mot clé 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() { 

    }; 
} 

instanciation autant d'objets de ce widget au besoin à l'aide,

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

Pardonnez mon ignorance, mais est-il vrai que lorsque vous utilisez ce modèle, je dois d'abord déclarer toutes les fonctions internes avant de les utiliser dans la fonction myExplorer environnante. Je suis juste un peu confus par votre code // init ici commentaire. – benb

2

Lorsque vous appelez $.extend() comme ça, il se confond la seconde propriétés de l'objet dans la première:

$.extend(myExplorer.config, settings); 

Au lieu de cela, créer un nouvel objet qui est le résultat de la fusion en laissant le premier objet (par défaut) intacte, comme ceci:

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

Qu'est-ce que cela ne fait fusionner encore les objets transmis dans le premier, mais le premier est un nouvel objet ({}), donc nous ne sommes pas affecter l'un ou l'autre, alors utilisez simplement this.settings (ou un nom différent pour le rendre absolument clair) à l'intérieur de votre objet.

+0

Merci. J'ai essayé mais ça n'a pas marché pour moi. Alors qu'il créait un nouvel objet settings dans l'objet myExplorer, les valeurs étaient toujours remplacées par le second appel myExplorer.init (settings). – benb

+0

@ben - Je ne regardais même pas la structure de votre objet, vous n'avez qu'un seul objet, vous devrez parcourir un chemin complètement différent pour créer votre objet en utilisant ce qui précède, la réponse d'Anurag est une possibilité, il y a beaucoup de motifs ici. –

8

Qu'en est-ce?

 
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

Utilisez le code suivant pour y parvenir, souvenez-vous de la « API publique » (fonction pour que la « interne » sera visible « en dehors »):

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

De ma compréhension que vous êtes essayer de créer une nouvelle instance d'objet qui a été définie en utilisant la notation littérale d'objet. Les littéraux d'objet peuvent être instanciés à l'aide de la méthode Object.create. Voici le code qui explique comment instancier un objet à partir de la notation littérale d'objet.

  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(); 
Questions connexes