AngularJS学习第二篇 AngularJS依赖注入
简介:
首先我们需要理解什么是依赖注入?
控制反转和依赖注入有什么区别?
假定:应用程序a,需要访问外部资源c。这里使用了容器b(是指用来实现 ioc/di 功能的一个框架程序)。
a需要访问c
b获取c然后返回给a
ioc inversion of control 控制反转:站在容器角度。b控制a,由b反向的向a注入c。即容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
di dependency injection 依赖注入:站在应用程序的角度。a依赖b获取c,b将c注入a。即应用程序依赖容器创建并注入它所需要的外部资源。
angularjs依赖注入
provider服务($provide)
angularjs 提供很好的依赖注入机制。以下5个核心组件用来作为依赖注入:
value
factory
service
provider
constant
decorator (打酱油)
constant
定义常量用的,这货定义的值当然就不能被改变,它可以被注入到任何地方,但是不能被装饰器(decorator)装饰
var app = angular.module('app', []); app.config(function ($provide) { $provide.constant('movietitle', 'the matrix'); }); app.controller('ctrl', function (movietitle) { expect(movietitle).toequal('the matrix'); }); // 语法糖: app.constant('movietitle', 'the matrix');
value
这货可以是string,number甚至function,它和constant的不同之处在于,它可以被修改,不能被注入到config中,但是它可以被decorator装饰
var app = angular.module('app', []); app.config(function ($provide) { $provide.value('movietitle', 'the matrix') }); app.controller('ctrl', function (movietitle) { expect(movietitle).toequal('the matrix'); }); // 语法糖: app.value('movietitle', 'the matrix');
service
它是一个可注入的构造器,在angularjs中它是单例的,用它在controller中通信或者共享数据都很合适。
var app = angular.module('app' ,[]); app.config(function ($provide) { $provide.service('movie', function () { this.title = 'the matrix'; }); }); app.controller('ctrl', function (movie) { expect(movie.title).toequal('the matrix'); }); // 语法糖: app.service('movie', function () { this.title = 'the matrix'; });
factory
它是一个可注入的function,它和service的区别就是:factory是普通function,而service是一个构造器(constructor),这样angular在调用service时会用new关键字,而调用factory时只是调用普通的function,所以factory可以返回任何东西,而service可以不返回(可查阅new关键字的作用)。
var app = angular.module('app', []); app.config(function ($provide) { $provide.factory('movie', function () { return { title: 'the matrix'; } }); }); app.controller('ctrl', function (movie) { expect(movie.title).toequal('the matrix'); }); // 语法糖 app.factory('movie', function () { return { title: 'the matrix'; } });
provider
provider是他们的老大,上面的几乎(除了constant)都是provider的封装,provider必须有一个$get方法,当然也可以说provider是一个可配置的factory。
var app = angular.module('app', []); app.provider('movie', function () { var version; return { setversion: function (value) { version = value; }, $get: function () { return { title: 'the matrix' + ' ' + version } } } }); app.config(function (movieprovider) { movieprovider.setversion('reloaded'); }); app.controller('ctrl', function (movie) { expect(movie.title).toequal('the matrix reloaded'); });
decorator
这个比较特殊,它不是provider,它是用来装饰其他provider的,而前面也说过,他不能装饰constant,因为实际上constant不是通过provider()方法创建的。
var app = angular.module('app', []); app.value('movietitle', 'the matrix'); app.config(function ($provide) { $provide.decorator('movietitle', function ($delegate) { return $delegate + ' - starring keanu reeves'; }); }); app.controller('mycontroller', function (movietitle) { expect(movietitle).toequal('the matrix - starring keanu reeves'); });
总结:
所有的供应商都只被实例化一次,也就说他们都是单例的
除了constant,所有的供应商都可以被装饰器(decorator)装饰
value就是一个简单的可注入的值
service是一个可注入的构造器
factory是一个可注入的方法
decorator可以修改或封装其他的供应商,当然除了constant
provider是一个可配置的factory
上述来源:(angularjs中的provider们:service和factory等的区别)https://segmentfault.com/a/1190000003096933
注入器($injector)
注入器负责从我们通过 provide 创建的服务中创建注入的实例。只要你编写了一个带有可注入性的参数,你都能看到注入器是如何运行的。每一个 angularjs 应用都有唯一一个 injector,当应用启动的时候它被创造出来,你可以通过将 injector 注入到任何可注入函数中来得到它($injector 知道如何注入它自己!)。
一旦你拥有了 injector,你可以动过调用 get 函数来获得任何一个已经被定义过的服务的实例。
var movie = $injector.get('movie'); expect(movie.title).toequal('the matrix reloaded');
注入器同样也负责将服务注入到函数中;例如,你可以魔法般的将服务注入到任何函数中,只要你使用了注入器的 invoke 方法:
var myfunction = function(movie) { return movie.title; }; $injector.invoke(myfunction);
如果注入器只是创建一个服务的实例一次的话,那么它也没什么了不起的。它的厉害之处在于,他能够通过服务名称缓存从一个 provider 中返回的任何东西,当你下一次再使用这个服务时,你将会得到同一个对象。
因此,你可以通过调用 injector.invike 将服务注入到任何函数中也是合情合理的了。包括:
- 控制器定义函数
- 指令定义函数
- 过滤器定义函数
- provider中的$get方法(也就是factory函数)
由于constant和value总是返回一个静态值,它们不会通过注入器被调用,因此你不能在其中注入任何东西。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。