2

そのため、1 つの js ファイルを使用して、必要なときに複数の html および js ファイルをロードします。たくさんのモジュールの作業コードがあります。以下の例では、最初の 2 つのモジュールを確認できます。それらはすべてまったく同じに見えます。ここで、繰り返しコードをパラメーター付きの関数に「アウトソーシング」して、全体的なコード量を最小限に抑えたいと考えています。私は助けが必要になる前にこのようなことをしたことがないので(私は現在jsを学んでいます)。助けていただければ幸いです。

 //first module
 if (moduleID === "placeone") {
            var isLoaded = 0;
            if (isLoaded) {
                console.log("file already loaded");
                returnValue = new PlaceOneModule(id, moduleInitialData);
            }
            $("#placeone").load("html/modules/PlaceOneModule.html", function (response, status, xhr) {
                console.log("PlaceOneModule.html" + " " + status);
                $.getScript("js/modules/PlaceOneModule.js").done(function () {
                    console.log("PlaceOneModule.js geladen");
                    isLoaded = 1;
                    returnValue = new PlaceOneModule(id, moduleInitialData);
                }).fail(function () {
                    console.log("PlaceOneModule.js nicht geladen");
                });
            });
        }

    //second module
        if (moduleID === "placetwo") {
            var isLoaded = 0;
            if (isLoaded) {
                console.log("file already loaded");
                returnValue = new PlaceTwoModule(id, moduleInitialData);
            }
            $("#placetwo").load("html/modules/PlaceTwoModule.html", function (response, status, xhr) {
                console.log("PlaceTwoModule.html" + " " + status);
                $.getScript("js/modules/PlaceTwoModule.js").done(function () {
                    console.log("PlaceTwoModule.js geladen");
                    isLoaded = 1;
                    returnValue = new PlaceTwoModule(id, moduleInitialData);
                }).fail(function () {
                    console.log("PlaceTwoModule.js nicht geladen");
                });
            });
        }
4

2 に答える 2

2

説明しなければならないことがたくさんあるので、この質問に答えるのはかなり複雑です。

var cache = {};

function module(name, target, done) {
    if (!(name in cache)) {
        return $(target).load('html/modules/' + name + '.html', function(response, status, xhr) {
            console.log(name + '.html ' + status);

            $.getScript('js/modules/' + name + '.js')
                .done(function() {
                    console.log(name + '.js geladen');
                    cache[name] = window[name];

                    done(null, cache[name]);
                })
                .fail(function() {
                    var message = name + '.js nicht geladen';

                    cache[name] = function() {
                        console.error(message);
                    };

                    done(message);
                });
        });
    }

    setTimeout(function() {
        done(null, cache[name]);
    }, 0);
}

この背後にある私の一連の考えを説明しようと思います。

  • var cache = {}- 個々のモジュールを追跡するために何かが必要になります
  • function module(name, target, done) {
    • nameモジュールのベース名になります。たとえばPlaceTwoModule、これはすでに html ファイルと js ファイル、および js 関数名で一貫して使用されています。
    • targethtmlファイルをロードするセレクターになります
    • 実行するアクションの 1 つに非同期操作が必要なため、機能全体を非同期にする必要があるため、コールバック ( done) 引数を導入します
  • if (!(name in cache))- モジュールがまだキャッシュされていない場合は、フェッチが必要になるため、load最初に がトリガーされます
  • load完了すると、$.getScript
    • がうまくいく$.getScriptと、が入っているnameと見なされwindow、参照が変数に格納されcacheます。その後、doneコールバックが呼び出されます (関数を 2 番目の引数として)。
    • $.getScriptがうまくいかなかった場合は、関数を に追加します。これは、機能cacheしないことを伝えるだけで、その後、doneコールバックが呼び出されます (最初の引数としてエラーが発生します)。
  • nameにが存在する場合は、関数を終了した直後にコールバックcacheを呼び出します。donemodule

では、これをどのように使用するのですか?module要約すると、関数を呼び出すことになります

module('#placeone', 'PlaceOneModule', function(error, PlaceModule) {
  if (error) throw new Error(error);

  var instance = new PlaceModule(id, initial);

  // ...
}

私はコールバック関数に共通のfunction(error, value) {..}署名を使用しました。これは常に最初の引数としてエラーを持ちます (他の引数を追加してオプションにすることができます)。

言及する価値のある警告/仮定がいくつかあります。

  • module以前の呼び出しがまだロードされている場合、同じモジュールの複数のロードを防ぐためのフェイルセーフを提供していません(したがって、例と同じです)
  • targetを呼び出しmoduleても、「1回」しかロードされません(前の行を参照してください;-))
  • 例を単純にするために、ロードされたモジュールはグローバル ( window) スコープにあると仮定します。「グローバル スコープを汚染」しないように注意してください。

これはかなり精巧な答えになりました。関連するすべてのステップを十分に説明したいと思います。

于 2016-02-08T09:33:08.763 に答える
1

おそらくこのようなもの:

 var modules = [];
 modules.push({
   js: 'PlaceOneModule',
   id: 'placeone'
 });

 modules.push({
   js: 'PlaceTwoModule',
   id: 'placetwo'
 });

 var module = modules.filter(function(m) {
   return m.id === moduleID;
 });

 if (module) {
   var isLoaded = 0;
   if (!!window[module.js]) {
      console.log("file already loaded");
      returnValue = window[module.js];
   }

   $("#" + module.id).load("html/modules/" + module.js + ".html", function(response, status, xhr) {
     $.getScript("js/modules/" + module.js + ".js").done(function() {
        returnValue = new window[module.js](id, moduleInitialData);
     }).fail(function() {
        console.log("PlaceOneModule.js nicht geladen");
     });
   });
 }
于 2016-02-08T08:54:34.227 に答える