2016-02-08 39 views
2

「外包」循環代碼到一個函數中,所以我使用一個js文件在需要時加載多個html和js文件。我有一個大量模塊的工作代碼。在下面的例子中,您可以看到前兩個模塊。他們都看起來完全一樣。現在我想將循環代碼「外包」到一個帶參數的函數中,這樣代碼總量就會最小化。因爲在我需要幫助之前我從未做過這樣的事情(我現在正在學習js)。我會真的很感激一些幫助。使用參數(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"); 
       }); 
      }); 
     } 

回答

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函數名稱
    • target將在HTML文件應該被加載
    • 你採取行動的一個選擇需要異步操作,全功能使用需要變得異步,我介紹一個回調(done)參數
  • if (!(name in cache)) - 如果該模塊還沒有緩存,它需要一些取,所以load被觸發第一件事
  • 一旦load完滿成功ES,這將觸發$.getScript
    • 如果$.getScript作品出去,name將被假定爲window和參考存儲在cache變量,在此之後,done調用回調函數(與功能第二個參數)。
    • 如果$.getScript沒有解決問題,我們給cache添加一個函數,它只會告訴你它不起作用,然後調用done回調函數(作爲第一個參數有一個錯誤)。
  • 如果namecache確實存在,我們將調用done回調之後,我們退出module功能

那麼,該如何使用呢? 現在歸結爲調用module功能

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

    var instance = new PlaceModule(id, initial); 

    // ... 
} 

我已經使用了常見的function(error, value) {..}簽名的回調函數,它總是有錯誤的第一個參數(允許添加並提出可選其他參數)。

還有值得一提的一些注意事項/假設:

  • 我沒有設置用於防止同一模塊的多個負載故障保護(所以它是相同的例子),如果以module較早電話是仍在加載
  • 不管你調用module什麼target,它只會加載「一次」(好,見前面的線;-))
  • 我假設加載的模塊在全球(window)範圍,以保持簡單的例子k不要忘記'pollute the global scope'

這已經成爲一個相當詳細的答案,我希望我解釋每一步都足夠。

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