使用全局对象避免角度依赖注入

时间:2017-09-15 16:28:25

标签: javascript angularjs dependency-injection global-variables

我继承了一些使用全局对象来存储角度服务的代码。这些服务在角度模块的run函数中附加到全局对象。我的问题是,这会导致路上的麻烦吗?这会给测试带来什么样的麻烦?传递这样的服务似乎比注入每个控制器中的所有服务容易得多,所以我明白为什么这样做。没有这样做的其他论据是什么?这里有一些代码来说明我在说什么:

// 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'];

2 个答案:

答案 0 :(得分:1)

这使得测试梦魇化。依赖注入很棒,因为它意味着您可以通过模拟不需要的服务来进行一些原子测试。在一个简单的,非紊乱的例子中,想象一个通过http进行API调用的服务,如果你把它调入,你的测试可以模拟出来并伪造一个返回,让你只测试你想要的代码位,以及使您免于进行依赖于API的测试,或者更糟糕的是使用API​​调用的测试套件。由于提供商处于全球范围,因此实现起来要困难得多。

只有一个原因,我确信还有很多其他原因。

答案 1 :(得分:1)

模块和DI在Angular中完全引入,以避免依赖全局变量并提高模块性。

这种天真的方法只有在有一个模块和一个应用程序实例时才有效。如果有多个模块可以单独使用(包括测试),它将失败。如果页面上有多个应用程序实例,则会产生可怕的错误(例如,如果Angular用于非SPA应用程序)。

monolith模块损害了可测试性。即使它被这样使用,一些选项也将不可用,例如在$controller(...)中注入spied或stubbed服务 - 因为控制器依赖于全局变量。

setUpGlobals导致急切的服务实例化。这可能不是核心服务的问题,但对于现在不需要实例化的服务来说将是一个问题。

不太重要的问题是缩小应用程序中的代码大小。 ng.$rootScope可以缩小为a.$rootScope但不能进一步缩小。注释函数应提及'$rootScope'字符串一次,但$rootScope变量名称可缩小为a。如果在函数内多次使用服务,则会有所改进。

有很多原因why global variables are bad。其中一些在这种情况下不适用,其他的将会适用。