2016-07-12 4 views
0

私はプロジェクト用に小さなjqueryプラグインを作成しています。それは基本的に、jsonファイルからプロジェクトのリストを取得して表示し、検索、追加、編集を可能にするプロジェクト管理アプリケーションです。それは素晴らしい作品ですが、私はちょっと "この"を使って正しく問題を抱えています。私は関数を使うたびにプラグインインスタンスを参照するために "this"を再キャッシュしなければなりません。私の質問は、これを行う正しい方法ですか?または、プラグインの初期化で何か問題があるのですか?Jquery Boilerplateのパラダイムを使用しているときに "this"をキャッシュする?

以下は私のコードのサンプルです。私のgetDataと私のページ設定関数を見ると、コンテキストと呼ばれるvarに "this"というキャッシュがあります。私はこのパラダイムを私のさまざまな機能を通して繰り返します。私が初期化中に "this"をキャッシュしようとすると、そのキャッシュされた変数を自分の関数全体で使用すると、1つのインスタンスしか認識されません。私はそれを再キャッシュしなければならない。

(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)); 
      } 
     }); 
    }; 

}

答えて

0

これはJavaScriptを使用して非常に共通の問題です。 thisdepends on how the function is being calledの値。したがって、関数を別の関数に渡すと、それは他の関数がそれをどのように呼び出すかによって異なります。

たとえば、$("ele").each(foo)を使用すると、現在の要素のコンテキストでfooが呼び出されます。

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

それに対処するいくつかの方法があります。あなたがすでに特定した最初の方法:変数に "this"を代入すると、変数は関数によって取り込まれます。 Function.bindを使用して、thisコンテキストを明示的に設定することもできます。

あなたはES6を使用することができるかどう

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

最後に、Arrow functionsthis自分自身を結合しません。したがって、新しいvarを作成せずにFunction.bindを呼び出すことなく動作します。

+0

お返事ありがとうございます。あなたがそれを必要とする度に変数に 'this'を割り当てると、パフォーマンス/スピードの問題はありますか?私のプログラムはかなり小さいので、それはあまりにも重要ではないと思うが、将来の参考のために私は知りたいと思う。私は、スコープを維持するためにbindを使うことについてどこか読んでいました。私の場合、どのように私はバインド関数を使用するのだろうか? –

+0

おそらく1つの変数はパフォーマンスの差を決して起こさないでしょう。バインドを使用すると、(フォーマットするための回答に移動した)ようになります。 この場合は、あなたが見たいと思っているところまでです。 –

関連する問題