2016-07-08 6 views
0

Ich habe sehr wenig Erfahrung beim Schreiben von jQuery-Plugins und noch weniger Erfahrung mit JavaScript-Design-Muster, also bitte mit mir ertragen.Erweitern/überschreiben jQuery Objekt literal Methoden - Out of Scope Ausgaben

Ich verwende das Singleton-Muster in einer jQuery-Erweiterung, die ich schreibe. Das funktioniert gut, aber ich möchte in der Lage sein, Methoden und Eigenschaften meines Singleton-Objekts zu erweitern/zu überschreiben.

Um dies zu erreichen, habe ich ein Master-Objekt var self = {}, das zur Laufzeit ein Eigenschaften-Objekt-Literal und ein Methoden-Objekt-Literal enthalten wird. Die einzelnen Eigenschaften und Methoden ihrer jeweiligen Objektliterale werden auf Standardwerte oder einen Optionsparameter gesetzt, wenn einer übergeben wurde.

Dies funktioniert auch, bis Sie eine Methode übergeben, die versucht, auf self.properties oder self.methods zuzugreifen. Da self nur im Singleton-Objekt und nicht im Objektliteral definiert ist, das ich übergeben möchte, wird ein JavaScript-Fehler ausgelöst, bevor überhaupt etwas übergeben wird.

Um dies besser zu verstehen, habe ich unten ein vollständiges Beispiel erstellt, das sehr genau dem ähnelt, was ich versuche zu tun.

;(function ($, window, document, undefined) { 
    $.extend({ 
     MyObject : function(options) { 

      // enfore singleton pattern 
      $.MyObject = function() { 
       if(typeof $.MyObject != 'undefined') { // if an instance exists 
        console.log('$.MyObject is a singleton - original instance returned'); 
        return $.MyObject; // return original instance 
       } 
       else return this; // else, return this instance 
      }; 

      var self = {}, 
      defaults = { 
       properties : { 
        prop : true, 
        foo : "bar" 
       }, 
       methods : { 
        main : function() { 
         console.log(self.properties.foo); // console logs "bar" 
        } 
       } 
      }; 

      this.init = function(options) { 
       self = $.extend({}, defaults, options); // set properties to defaults unless options were provided 
       self.methods.main(); 
      }; 

      this.init(options); 

      return this; 
     } 

    }); 

})(jQuery, window, document); 

$(window).load(function() { 
    $.MyObject({ 
     properties : { 
      foo : "baz" 
     }, 
     methods : { 
      main : function() { 
       if(self.properties.prop) { // Uncaught TypeError: Cannot read property 'prop' of undefined 
        console.log(self.properties.foo); // Uncaught TypeError: Cannot read property 'foo' of undefined 
       } 
      } 
     } 
    }); 
}); 

Ich habe wahrscheinlich drastisch überkompliziert, was ich versuche zu tun. An dieser Stelle denke ich, dass es wahrscheinlich einen besseren Weg gibt, dies zu tun.

Irgendwelche Gedanken?

Antwort

1

Wahrscheinlich möchten Sie eine tiefe Erweiterung in init(). Sie könnten die aktuellen Optionen auch als "this" über call() auf main() übergeben.

;(function ($, window, document, undefined) { 
 
    $.extend({ 
 
    MyObject : function(options) { 
 

 
     // --------------- 
 
     // enforce singleton pattern 
 
     // --------------- 
 
     $.MyObject = function() { 
 
     if (typeof $.MyObject === 'undefined') { return this; } 
 
     console.log('$.MyObject is a singleton...'); 
 
     return $.MyObject; 
 
     }; 
 
     // --------------- 
 

 
     // --------------- 
 
     // establish default options 
 
     // --------------- 
 
     var self = {}; 
 
     var defaults = { 
 
     properties : { 
 
      prop : true, 
 
      foo : "bar" 
 
     }, 
 
     methods : { 
 
      main : function() { console.log(this.properties.foo); } 
 
     } 
 
     }; 
 
     // --------------- 
 

 
     // --------------- 
 
     // Override default options and execute main() in the context 
 
     // of our current options 
 
     // --------------- 
 
     this.init = function(options) { 
 
     self = $.extend(true, {}, defaults, options); 
 
     self.methods.main.call(self); 
 
     }; 
 
     this.init(options); 
 
     // --------------- 
 

 
     return this; 
 
    } 
 
    }); 
 
})(jQuery, window, document); 
 

 
$(window).load(function() { 
 
    var options = { 
 
    properties : { 
 
     bar : "foo" 
 
    }, 
 
    methods : { 
 
     main : function() { 
 
     if(this.properties.prop) { console.log(this.properties.bar); } 
 
     } 
 
    } 
 
    }; 
 

 
    $.MyObject(options); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

+0

Aw Mann, ich war in der Nähe. Ich bin nicht vertraut mit der tiefen Erweiterung oder der Call() -Funktion, aber ich werde lernen, diese zu studieren. Danke für Ihre Hilfe! –