Angular开发者指南(七)依赖注入
依赖注入
工厂方法 angular.module('myModule',[]) .factory('serviceId',['depService',function(depService) { // ... }]) .directive('directiveName',function(depService) { // ... }]) .filter('filterName',function(depService) { // ... }]); 模块方法 angular.module('myModule',[]) .config(['depProvider',function(depProvider) { // ... }]) .run(['depService',function(depService) { // ... }]); 控制器 someModule.controller('MyController',['$scope','dep1','dep2',function($scope,dep1,dep2) { ... $scope.aMethod = function() { ... } ... }]); 与服务不同,应用程序中可能有许多相同类型的控制器实例。 此外,对控制器提供附加的依赖性:
依赖注解
内联数组注解 someModule.controller('MyController','greeter',greeter) { // ... }]); 这里我们传递一个数组,其元素由一个字符串列表(依赖项的名称)和函数本身组成。 var MyController = function($scope,greeter) { // ... } MyController.$inject = ['$scope','greeter']; someModule.controller('MyController',MyController); 在这种情况下,$inject数组中的值的顺序必须与MyController中的参数的顺序匹配。 someModule.controller('MyController',greeter) { // ... }); 给定一个函数,注入器可以通过检查函数声明并提取参数名称来推断要注入的服务的名称。 在上面的例子中,$scope和greeter是需要注入到函数中的两个服务。 <!doctype html> <html ng-app="myApp" ng-strict-di> <body> I can add: {{ 1 + 2 }}. <script src="angular.js"></script> </body> </html> 只要服务尝试使用隐式注解,严格模式就会抛出错误。 angular.module('myApp',[]) .factory('willBreak',function($rootScope) { // $rootScope是被隐式注解 }) .run(['willBreak',function(willBreak) { //当它运行时AngularJS抛出这个异常 }]); 当willBreak服务被实例化时,AngularJS将抛出一个错误,因为严格的模式。 当使用ng-annotate等工具确保所有应用程序组件都有注解时,这是非常有用的。 angular.bootstrap(document,['myApp'],{ strictDi: true }); 为什么要依赖注入?
创建或查找依赖关系的前两个选项不是最优的,因为它们会对组件的依赖性进行硬编码。这使得很难,即使不是不可能,修改依赖性。这在测试中尤其成问题,其中通常期望提供用于测试隔离的模拟依赖性。 function SomeClass(greeter) { this.greeter = greeter; } SomeClass.prototype.doSomething = function(name) { this.greeter.greet(name); } 在上面的例子中,SomeClass不关心创建或定位greeter依赖,它只是在实例化时传递给greeter。 // 在模块中提供连接信息 var myModule = angular.module('myModule',[]); 指示注入器如何建立一个greeter服务。 注意greeter依赖于$window服务。 greeter服务是一个包含greet方法的对象。 myModule.factory('greeter',function($window) { return { greet: function(text) { $window.alert(text); } }; }); 创建一个新的注入器,它可以提供myModule模块中定义的组件,并从注入器请求我们的greeter服务。 (这通常由AngularJS引导自动完成)。 var injector = angular.injector(['ng','myModule']); var greeter = injector.get('greeter'); 请求依赖性解决了硬编码的问题,但它也意味着注入器需要在整个应用程序中传递。 通过注入器打破了Demeter的定律。 为了弥补这一点,我们在HTML模板中使用声明符号,将创建组件的责任交给注入器,如下例所示: <div ng-controller="MyController"> <button ng-click="sayHello()">Hello</button> </div> function MyController($scope,greeter) { $scope.sayHello = function() { greeter.greet('Hello World'); }; } 当AngularJS编译HTML时,它会处理ng-controller指令,然后请求注入器创建控制器及其依赖关系的实例。 injector.instantiate(MyController); 这一切都在幕后完成。 注意,通过让ng-controller要求注入器实例化类,它可以满足MyController的所有依赖性,而控制器不知道注入器。这是最好的结果。 应用程序代码简单地声明它需要的依赖性,而不必处理注入器。 这个设置不打破德米特法。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- twitter-bootstrap – MVC Bootstrap形成样式问题
- Bootstrap 模态框垂直居中处理
- angularjs – 使用css元素来检查量子变量中是否存在元素
- webservice (二) 初次尝试
- angular js(2)和ionic(2)的总结
- Advanced Programming in UNIX Environment Episode 17
- angularjs – 如何用角度的pushstate URL抛出一个真正的404
- Shell脚本自动输入EOF error :end-of-file
- BootStrap 管理系统框架选择
- 为什么ListNode示例(Scala网站)可以处理不同的类型?