Angular.js中的$injector服务

一 、angular中的依赖注入

  angular的一个很重要的特性就是依赖注入,可以分开理解这4个字。

  1.依赖:

    angular里面的依赖,有angular默认提供的,也有我们自己添加的。默认提供的比如$rootScope$http$injector等,我们也可以自己写factory函数来添加自己的依赖对象。

  2.注入:

    想要在当前上下文中使用已有的依赖,就必须通过$injector服务来获得依赖对象。

 

二、在一无所有的情况下获得$injector服务

 

  $injector本身也是依赖之一,怎么样一无所有的情况下得到$injector呢?angular框架提供了angular.injector()全局函数。

 

  这个函数接受modules数组作为它的参数,之后它就可以获得这些modules里面注册的各种服务了。特别是ng module,它是angular提供给我们的基础模块,$inject$rootscope$http等很多大家熟悉的服务都在ng module里面定义的。  

  看看下面代码:

<!doctype html>
<html>
<head>
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
    <script>
        var $injector=angular.injector(['ng']);
        var $log=$injector.get('$log');
        $log.log('hello world!');
    </script>
</head>
<body>
</body>
</html>

  大家发现这里没有ng-app属性,也没有angular.bootstrap()函数,但是我们得到了angularjs里面的$log服务。

 

三、angular启动过程中的$injector

 

  在angular.bootstrap()函数里和$injector有关系的语句如下:

modules = modules || [];
modules.unshift(['$provide', function($provide) {
  $provide.value('$rootElement', element);
}]);
modules.unshift('ng');
var injector = createInjector(modules, config.strictDi);
injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
       function bootstrapApply(scope, element, compile, injector) {
        scope.$apply(function() {
          element.data('$injector', injector);
          compile(element)(scope);
        });
      }]

  这里的代码说明了angular启动过程中和我们前面的代码做了差不多的事情。

 

四、$injector和单元测试

 

  我们平时写angular程序的时候$injector用处可能不是很大,毕竟controller等函数都在暗中帮我们把注入做好了。但是在写单元测试的时候,就不得不用到$injector了。

!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="//cdn.bootcss.com/jasmine/2.4.1/jasmine.css">
  <script src="//cdn.bootcss.com/jasmine/2.4.1/jasmine.js"></script>
  <script src="//cdn.bootcss.com/jasmine/2.4.1/jasmine-html.js"></script>
  <script src="//cdn.bootcss.com/jasmine/2.4.1/boot.js"></script>
  <script src="//cdn.bootcss.com/angular.js/1.4.8/angular.js"></script>
  <script src="//cdn.bootcss.com/angular.js/1.4.8/angular-mocks.js"></script>
</head>
<body>
  <script>
    angular.module('myModule', [])
      .factory('myLog', ['$log', function ($log) {

        return {
          log: function(message) {
            $log.log(message);
            return $log;
          }
        }
    }]);
    describe('myLog tests', function () {
      var myLog;
      beforeEach(module('myModule'));
      beforeEach(inject(function (_myLog_) {
        myLog = _myLog_;
      }));

      it('should log what my writting', function () {
        expect(myLog.log('hello world').log.logs).toContain(['hello world']);
      });
    });
  </script>
</body>
</html> 

  以上代码中module('myModule')可以看成是var aa = angular.injector(['ng','ngMock','myModule']);,而后面的injector(function(_myLog_)...可以看成aa.invoke(['myLog',function(myLog){...

 

 

 

 

 

 

你可能感兴趣的:(Angular.js中的$injector服务)