2015-04-20 56 views
0

我具有如我加載僱員部及其腳本作爲index.html的一部分javascript如何檢測函數的定義,頂部/底部?

的index.html Working Demo

<!DOCTYPE html> 
<html> 

    <head> 
    <meta charset="utf-8" /> 
    <title></title> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="jquery" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script> 
    <script src="script.js"></script> 
    </head> 

    <body> 
    <h1>Employee Details loaded as usual and sript is executing able to see alert</h1> 
    </body> 

</html> 

的script.js

var empModule = (function (empModule) { 
    var Years = null; 

    $(document).ready(function() { 
     var empdata = { Name: 'Billa' } 
     var myVM = new empModule.viewModel(empdata); 

    }); 

    empModule.viewModel = function (data) { 
     var that = this; 
     that.Name = data.Name; 
     alert(that.Name); 
    }; 

    return { 
     empModule: empModule 
    } 
} (empModule || {}));    
以下代碼工作只要

錯誤情景:

我們決定移動員工r高興的部分基於某種條件。因此,我們通過Ajax加載這個部分和部分相關的腳本(emp.js)。但現在它拋出錯誤empModule.viewModel is not a constructor。爲什麼這樣?

如果我在移動像以下順序底部的document.ready部,它是工作

Emp.js(從移動的script.js通過AJAX到emp.js和負載(

var empModule = (function (empModule) { 
var Years = null; 
// Code not working when we load this script file using Ajax.    
// But works if we move this document.ready at bottom 
//$(document).ready(function() { 
    // var empdata = { Name: 'Billa' } 
    // var myVM = new empModule.viewModel(empdata); 

//}); 
empModule.viewModel = function (data) { 
    var that = this; 
    that.Name = data.Name; 
    alert(that.Name); 
}; 
//Working only if I keep the ready section here 
$(document).ready(function() { 
    var empdata = { Name: 'Billa' } 
    var myVM = new empModule.viewModel(empdata); 

}); 

return { 
    empModule: empModule 
} 
} (empModule || {})); 

功能empModule,因爲它是自 執行功能將得到自動執行。當執行它需要準備 empModule.viewModel對象,但未能這樣做,當視圖模型 定義位於document.ready(調用者)之後。這種情況僅 當我加載通過Ajax這個腳本,但如果我預先在一個頁面

+0

你能告訴你是如何加入腳本?你什麼時候期待使用它?例如'$(document).ready(// call module emp)'? – Matho

+0

@Matho,函數'empModule'將自動執行,因爲它是自執行函數。當它正在執行時,它需要準備一個empModule.viewModel對象,但是當viewModel定義位於document.ready(caller) – Billa

+0

閱讀關於[function hosting](http://adripofjavascript.com/blog/drips /variable-and-function-hoisting.html) –

回答

1

這是因爲在第一個例子中script.js是文檔的一部分,因此document.ready等待該.js加載它的工作原理要在調用empModule.viewModel()之前加載文件。

在第二個示例中,腳本異步加載,但頁面沒有考慮到這一點。因此,頁面加載(沒有script.js),然後加載腳本。 此時,文檔已準備好(因爲ajax加載的腳本不是文檔的一部分),所以empModule.viewModel()調用在腳本的其餘部分(這是定義函數的位)之前立即觸發,並且您獲得你的錯誤。

+0

因此,當我們異步加載scriipt時,我們總是/必須需要定義document.ready函數上方的函數/變量? – Billa

0

就像@dougajmcdonald說是你的問題,但你的解決方案,而不是通過loadding AJAX,只需插入腳本標籤文檔中:

// Instead of $.ajax(... /myScript.js) use: 

function loadMyScript(){ 
     var script = document.createElement("script"); 
     script.type = "text/javascript"; 
     script.src = 'myScript.js'; 
     script.onload = function() {       
      empModule.doSomething(); // or callback 
     }; 
} 
+0

我不認爲它是一個好主意,在dom中插入腳本 – Billa

+0

我沒有看到任何消極的方面,但如果你仍然不想添加它,可能你應該等到文檔被加載,然後使AJAX請求腳本,在'callback'裏面執行你的empModule。doSomething()'代碼 – Matho