1

我繼承了一些使用全局對象來存儲角度服務的代碼。這些服務通過角度模塊的運行功能附加到全局對象。我的問題是,這是否會導致麻煩?測試造成了什麼樣的麻煩?像這樣傳遞服務似乎比注入每個控制器中的所有服務容易得多,所以我明白了爲什麼這樣做。沒有這樣做的其他理由是什麼?下面是一些代碼來說明我在說什麼:使用全局對象避免角度依賴注入

// vars 
var globalObject = 
{ 
    ng: {}, 
}; 

// Setup module 
var myModule = angular.module("myModule", []); 
myModule.config(doStuff); 
myModule.run(setUpGlobals); 

// Setup app globals 
function setUpGlobals(ngRootScope, ngHttp, ngTimeout) 
{ 
    globalObject.rootScope = ngRootScope; 

    // angular services 
    globalObject.ng.http = ngHttp; 
    globalObject.ng.Timeout = ngTimeout; 
} 
setUpGlobals.$inject = ['$rootScope', '$http', '$timeout']; 

回答

1

模塊和DI都是在Angular中引入的,以避免依賴全局和提高模塊性。

這是天真的方法,只有在有單個模塊和單個應用程序實例時纔有效。如果有幾個模塊可以單獨使用(包括測試),它將會失敗。如果頁面上有多個應用程序實例(例如,如果Angular用於非SPA應用程序),它會產生可怕的錯誤。

整體模塊損害可測試性。即使這樣使用,一些選項也是不可用的,例如,在$controller(...)中注入spied或stubbed服務 - 因爲控制器依賴於全局變量。

setUpGlobals導致急切的服務實例化。這對核心服務來說可能不是問題,但對於現在不需要實例化的服務而言,這會是一個問題。

不太重要的問題是縮小應用程序中的代碼大小。 ng.$rootScope可以縮小到a.$rootScope,但沒有更多。註釋函數應該提及'$rootScope'一次字符串,但$rootScope變量名可以縮小爲a。如果服務在函數中多次使用,將會有所改進。

有很多原因why global variables are bad。其中一些在這種情況下將不適用,其他則會。

+0

謝謝!我不知道服務是按需實例化的。 https://www.bennadel.com/blog/2715-services-and-factories-are-instantiated-on-demand-in-angularjs.htm –

+1

不客氣。大多數時候這不會是一個問題,但是這可能會破壞依賴於自然行爲的功能,例如延遲加載。 – estus

+0

還有一個問題:服務在不同模塊中扮演單身人士的角色嗎?他們爲同一模塊做,但如果模塊A和模塊B注入服務1,服務1將被共享? –

1

這使得測試噩夢。依賴注入很棒,因爲它意味着你可以通過嘲笑你不需要的服務來進行一些原子測試。在一個簡單的,非參考性的例子中,設想一個通過http進行API調用的服務,如果你使用它,你的測試可以模擬出http並假裝一個返回,讓你只測試你想要的代碼位,使您不必進行依賴API的測試,或者更糟糕的是使用API​​調用的測試套件。隨着全球範圍內的供應商,這是更難以實現的。

只是一個原因,我敢肯定還有很多其他的。

+0

實際上,測試不會那麼糟糕 - 只要有一個模塊,全局變量就會在每次測試中重新分配。但重要的是它並不一定是單一的。一旦沒有,就會出現問題。 – estus