2016-07-12 3 views
0

Ich erstelle ein kleines jquery-Plugin für ein Projekt. Es ist im Grunde eine Projektmanagement-App, die eine Liste unserer Projekte aus einer JSON-Datei abruft, anzeigt und uns erlaubt, zu suchen, hinzuzufügen und zu bearbeiten. Es funktioniert gut, aber ich habe ein paar Probleme mit "this". Jedes Mal, wenn ich eine Funktion verwende, muss ich "this" neu cachen, um auf die Plugins-Instanz zu verweisen. Meine Frage ist, ist das der richtige Weg das zu tun? Oder mache ich etwas falsch in meiner Plugins-Initialisierung?Caching "dies" bei Jquery Boilerplate Paradigma?

Unten ist ein Beispiel meines Codes. Wenn Sie in meine getData und meine paginate Funktion schauen, sehen Sie, dass ich "dieses" in einem var genannten Kontext cache. Ich wiederhole dieses Paradigma in meinen verschiedenen Funktionen. Wenn ich versuche, "this" während der Initialisierung zwischenzuspeichern und dann diese zwischengespeicherte Variable in meiner gesamten Funktion zu verwenden, erkennt sie nur eine Instanz. Ich muss es immer wieder zwischenspeichern.

(function($, window, document, undefined) { 
    var pluginName = "ezProjectList", 
     defaults = { 
      jsonURL:"the URL", 
      status: "", 
      dateText: "" 
     }; 
    var jsonData = {}; 
    var string = {}; 
    var updateObj = {}; 
    var currentObject = {}; 
    var allData = {}; 
    var contexts = { 
     "contextone": undefined, 
     "contexttwo": undefined 
    } 
    var updateBoth; 

    function Plugin(element, options) { 
     this._element = element; 
     this._defaults = defaults; 
     this.options = $.extend({}, this._defaults, options); 
     this.init();  
    } 
    $.extend(Plugin.prototype, { 
     init: function() { 
      this.getData(); 
      $this = $(this); 

     }, 
     getData: function() { 
      var context = this; 
      console.log(context); 
      console.log(this); 
      if (contexts[0] == undefined) { 
       contexts[0] = this; 
      } else { 
       contexts[1] = this; 
      } 
      $.ajax({ 
       type: "GET", 
       url: context.options.jsonURL, 
       success: function(data) { 
        allData = data; 
        jsonData = data.projects[context.options.status]; 
        context.sortProjects(jsonData); 
        context.createPages(4) 
       } 
      }).done(function() { 
       context.paginate(); 
       context.setupEditForm(); 
       context.addProject(); 
       context.searchProjects(); 
       context.expandImages(); 
      }); 
     }, 
paginate: function(nav) { 
      //Creates pagination from the pages 
      var context = this; 
      nav = $(this._element).next().attr("id"); 
      $("#" + nav).jPages({ 
       containerID: $(context._element).attr("id"), 
       perPage: 1 
      }); 
     }; 
$.fn[pluginName] = function (options) { 
     var self = this; 
     return this.each(function() { 
      if (!$.data(self, "plugin_" + pluginName)) { 
       $.data(self, "plugin_" + pluginName, 
       new Plugin(self, options)); 
      } 
     }); 
    }; 

}

Antwort

0

Dies ist ein sehr häufiges Problem mit JavaScript. Der Wert thisdepends on how the function is being called. Wenn Sie eine Funktion an eine andere Funktion übergeben, hängt es daher davon ab, wie die andere Funktion sie aufruft.

Zum Beispiel, wenn $("ele").each(foo) verwendet wird, wird foo im Kontext des aktuellen Elements aufgerufen.

More importantly, the callback is fired in the context of the current DOM element, so the keyword this refers to the element.

gibt es ein paar Möglichkeiten, mit ihm fertig zu werden. Der erste Weg, den Sie bereits identifiziert haben: Weisen Sie "this" einer Variablen zu und die Variable wird von der Funktion erfasst. Sie können auch Function.bind verwenden, um den Kontext this explizit festzulegen.

z.B.

this.each(function() { 
    if (!$.data(this, "plugin_" + pluginName)) { 
     $.data(this, "plugin_" + pluginName, 
      new Plugin(this, options)); 
    } 
}.bind(this)); 

Schließlich, wenn Sie ES6 verwenden können, Arrow functions binden nicht ihre eigenen this. Sie arbeiten also, ohne eine neue Variable zu erstellen oder Function.bind aufzurufen.

+0

Danke für die Antwort. Gibt es Leistungs-/Geschwindigkeitsprobleme bei der Zuweisung von "this" zu einer Variablen, wenn Sie sie benötigen? Mein Programm ist ziemlich klein, also denke ich nicht, dass es zu viel bedeuten würde, aber nur für zukünftige Referenz möchte ich wissen. Ich hatte irgendwo gelesen, wie man bind benutzt, um den Umfang zu erhalten. In meinem Fall, wie würde ich die Bindefunktion verwenden? –

+0

Eine Variable wird wahrscheinlich nie einen Leistungsunterschied machen. Die Verwendung von bind würde wie folgt aussehen (verschoben um die Formatierung zu beantworten). In diesem Fall ist es das, was Sie bevorzugen. –