检查是否在Angular中注入依赖项

时间:2015-07-05 02:54:53

标签: javascript ajax angularjs internet-explorer caching

正如所讨论的here,IE在使用ajax(即$ route和$ http)时缓存了一些东西。可以找到这个问题的出色解决方案here

我们在网站上使用许多角度应用,因此为了确保其他角度应用的其他开发人员不会出现缓存问题,我想添加上面提出的解决方案我们网站上的每个Angular应用程序都是理所当然的。如果我们的样式指南包括以下内容,开发人员在构建自己的应用程序时更有可能包含它,并且可以成功避免非常危险的IE问题。毕竟,我认识的开发人员不再是在IE中积极开发的了。

var myApp = angular.module('myApp', ['ngRoute']);

myApp.config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) {
    $httpProvider.defaults.cache = false;
    if (!$httpProvider.defaults.headers.get) {
      $httpProvider.defaults.headers.get = {};
    }
    // disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
    // routes go here...
}]);

这段代码的作用是强迫IE不要缓存模板并发出$ http调用的服务器请求,而不是从缓存中提取结果(如果你的数据是动态的,这可能非常糟糕 - 这很可能是)。

为每个Angular应用程序添加上面的代码的问题是应用程序可能会或可能不会将ngRoute注入到应用程序的依赖项中。如果不存在ngRoute,则会发生注入错误。

所以,问题是:是否有可能检查Angular中是否存在注入的依赖项?我希望能够做到以下几点:

var myapp = angular.module('ordersApp', [
    'ngTouch',
    'ngRoute',
    'ngAnimate',
    'myController'
]);

if(myapp.has_ngRoute) {
     myapp.config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) {
    $httpProvider.defaults.cache = false;
         if (!$httpProvider.defaults.headers.get) {
             $httpProvider.defaults.headers.get = {};
         }
         // disable IE ajax request caching
        $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
        // routes go here...
    }]);
}

2 个答案:

答案 0 :(得分:2)

有两种方法可以解决这个问题:

1。检查服务是否存在并根据

运行行为

这可以回答您的具体问题 - 仅在服务存在的情况下运行代码

您可以使用$injector.has(...)查看提供商/服务是否已注册。

您可以检查$routeProvider是否已注册,并配置HTTP标头(如果存在)。

以下是我们在配置$routeProvider之前检查$httpProvider的示例。

// Cache configuration behaviour.
var configureCache = ['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.cache = false;
        if (!$httpProvider.defaults.headers.get) {
            $httpProvider.defaults.headers.get = {};
        }
        // disable IE ajax request caching
        $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
}];


angular.module('testApp', [
        // Test this by commenting this out.
        'ngRoute'
    ])
    .config(['$injector', function($injector){
        if ($injector.has('$routeProvider')){
            // If $routeProvider has been registered then
            // configure the $httpProvider.
            console.log('Has $routeProvider: configuring cache.');

            // Use `$injector.invoke(...)` so we can use
            // Angular dependency injection in our
            // configuration function above.
            $injector.invoke(configureCache);
        } else {
            // Otherwise don't do anything.
            console.log('Skipping cache configuration.');
        }
}]);

以下是Plunker中的示例: http://plnkr.co/edit/orXOjMg0YZXDfwoqf9OD

2。将代码拆分为模块

不检查模块/服务是否存在,使用模块依赖性来控制它

使用这种方法我们可以获得更大的灵活性。您定义缓存行为 在其自己的模块中,它依赖于ngRoute

当您包含缓存自定义行为时,您知道ngRoute必须存在,因为它是依赖项之一!

这为您提供了三种控制路由/缓存行为的方法 应用程序仅取决于您包含的模块:

没有路线

angular.module('testApp', [
        // Don't add 'ngRoute' module dependency here
        // or alter the caching behaviour.
    ])

路由但具有默认缓存行为

angular.module('testApp', [
        'ngRoute'
    ])

具有自定义缓存行为的路由

angular.module('testApp', [
        'noCacheRoutes'
    ])

在每种情况下,我们只需要更改模块依赖项,但有 以已知的方式改变了应用程序的行为。

以下是拆分缓存配置行为的示例 进入一个单独的模块:

/**
 * We decide that it only make sense to use this 
 * module along with `ngRoute` so define it as
 * a dependency here.
 */
angular.module('noCacheRoutes', [
        'ngRoute'
    ])
    .config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.cache = false;
        if (!$httpProvider.defaults.headers.get) {
            $httpProvider.defaults.headers.get = {};
        }
        // disable IE ajax request caching
        $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
    }]);


/**
 * Don't reference `ngRoute` here, let `noCacheRoutes`
 * bring it in as a transitive dependency.
 * 
 * If later on you decide you don't need to change
 * the caching behaviour you can just replace `noCacheRoutes`
 * with `ngRoute` and don't need to make any further changes.
 */
angular.module('testApp', [
        'noCacheRoutes'
    ])
    .config(['$routeProvider', function($routeProvider) {
        // Configure your application routes here.
    }]);

答案 1 :(得分:0)

正如此处AngularJs - get list of all registered modules所述,没有获取模块列表的方法,但您可以扩展角度模块方法(参见接受的答案)。