Freewind @ Thoughtworks scala java javascript dart 工具 编程实践 月结 math python english [comments admin] [feed]

(2013-01-01) 29. 把服务注入到控制器中

广告: 云梯:翻墙vpn (省10元) 土行孙:科研用户翻墙http proxy (有优惠)

在controller中使用services当作依赖与一个service把另一个service当作依赖的情况是非常相似的。

由于JavaScript是动态类型语言,DI无法像静态语言那样,由类型找到需要注入的service。因此,你需要使用$inject属性来指明用哪一种service,$inject是一个包含了service名称的由字符串组成的数组。Service ID的顺序很重要,注入的顺序与声明的顺序相同。但service的名字不重要,但它们通常与service的ID相同,以便于查看和修改。

function myController($loc, $log) {
this.firstMethod = function() {
 // use $location service
 $loc.setHash();
};
this.secondMethod = function() {
 // use $log service
 $log.info('...');
};
}
// which services to inject ?
myController.$inject = ['$location', '$log'];

### 源代码

**index.html**

<!doctype html>
<html ng-app="MyServiceModule">
  <head>
    <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="myController">
      <p>Let's try this simple notify service, injected into the controller...</p>
      <input ng-init="message='test'" ng-model="message" >
      <button ng-click="callNotify(message);">NOTIFY</button>
    </div>
  </body>
</html>

**script.js**

angular.
 module('MyServiceModule', []).
 factory('notify', ['$window', function(win) {
    var msgs = [];
    return function(msg) {
      msgs.push(msg);
      if (msgs.length == 3) {
        win.alert(msgs.join("\n"));
        msgs = [];
      }
    };
  }]);

function myController(scope, notifyService) {
  scope.callNotify = function(msg) {
    notifyService(msg);
  };
}

myController.$inject = ['$scope','notify'];

**End to end test**

it('should test service', function() {
  expect(element(':input[ng\\:model="message"]').val()).toEqual('test');
});

jsfiddle TODO

#### 隐式注入

Angular DI的一个新特性是从参数名称来决定使用哪些依赖。让我们重写上面的例子,来演示隐式依赖注入`$window`,`$scope`和我们自定义的`notify` service:

### 源代码

**index.html**

<!doctype html>
<html ng-app="MyServiceModuleDI">
  <head>
    <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="myController">
      <p>Let's try the notify service, that is implicitly injected into the controller...</p>
      <input ng-init="message='test'" ng-model="message">
      <button ng-click="callNotify(message);">NOTIFY</button>
    </div>
  </body>
</html>

**script.js**

angular.
 module('MyServiceModuleDI', []).
 factory('notify', function($window) {
    var msgs = [];
    return function(msg) {
      msgs.push(msg);
      if (msgs.length == 3) {
        $window.alert(msgs.join("\n"));
        msgs = [];
      }
    };
  });

function myController($scope, notify) {
  $scope.callNotify = function(msg) {
    notify(msg);
  };
}

jsfiddle demo

但是,如果你想最小化你的代码(参见:http://en.wikipedia.org/wiki/Minification_(programming)),你的参数名可能会被修改,这样你还得使用$inject属性再次显式声明你的依赖。

相关API

comments powered by Disqus