你的位置:首页 > Java教程

[Java教程]AngularJS注册和使用服务和常量(provider、factory、service、constant、value)


1.   简介

AngularJS采用MVC架构,提供了服务的注册和以依赖注入方式使用服务的机制。服务是功能(方法)和数据(常量)的抽象,比如系统中关于用户信息相关的功能(头像、昵称、签名、生日、性别等信息的获取与修改)抽象后集中在一个对象中,那么这个对象就可以视为一个服务。服务可以通过angular.Module(常以var app = angular.module('my-app',[])方式获取)和$provider(以依赖注入方式获取)对象注册,常以依赖注入的方式使用使用。

每个服务有一个(字符串类型的)名字,在注册时提供,依赖注入子系统通过服务名获得服务对象。服务是单例的,因此每次获取到的服务都是同一个服务对象。

下面通过一个简单的示例来说明如何在代码中注册和使用服务,以及可能遇到的一个坑(依赖注入器$injector找不到服务Error: [$injector:unpr] Unknown provider: XXXXXX。通过查看源码发现angular注册服务时会在服务名后自动添加后缀"Provider",我之前有遇到依赖注入器死活找不到对应服务名,在我往依赖注入变量名后手动添加Provider后运行成功,但此问题没能重现,因此不能详解)。这个示例很简单,只是显示通过服务注册的5种方式(provider、factory、service、constant、value)注册服务(和数据),然后通过依赖注入的方式获取服务和数据,之后在网页上显示出。

5种方式中,后4种都是依赖于provider方式实现的,5种方式依次更特殊,更不灵活,注册也因此变得更简单。

2.   provider方式

用provider注册服务常见的调用形式是:

var app = angular.module('app', []);app.provider('StarProvider', function () {  console.log('provider constructor')  //必须定义$get函数  this.$get = function () {    console.log('provider $get func')    var counter = 0;    var obj = function () {    };    obj.favorite = function () {      return '李嘉欣x' + counter++;    };    return obj;  }});

provider函数中的重点是第二个参数,这个参数中必须定义$get函数,这将成为取得服务对象的getter函数。

3.   factory方式

factory方式注册时,形式上类似provider,不同的是,第二个参数是一个工厂函数,该函数是一个有返回值的函数,返回值就是服务对象,angular在实现factory方式时,就是将factory第二个参数作为一个新对象的$get属性传递给provider,作为其第二个参数。

代码形式通常为:

app.factory('StarFactory', function () {  console.log('factory constructor')  var c = 0;  var fac = {};    // 常先定义一个服务对象,然后定义其服务接口  fac.favorite = function () {    return '关之琳x' + c++;  };  return fac;});

4.   service方式

factory到service的特殊化程序类似provider到factory,service的第二个参数不使用factory中的工厂模式,第二个参数就是服务对象的构造器,其中定义的公有属性就是服务的服务接口。可见,不像factory方式,service方式不再在第二个参数(可执行对象)中定义服务对象(上例中的fac变量),因其就是服务对象本身。以该方式注册服务的代码常以以下形式出现:

app.service('StarService', function () {  console.log('service constructor')  var c = 0;  this.favorite = function () {    //常以this.xxx方式定义服务接口    return '蓝洁瑛x' + c++;  }})

5.   constant、value方式

这两种方式用以注册常量(不变的量,并非就一定是字符串或数值类型),二者区别小,且不常被我使用,不详解,注册代码形式为:

app.constant('StarConstant', '邱淑贞-const');app.value('StarValue', '梅艳芳-val');

6.   服务使用方式(依赖注入)

三种依赖注入使用方式:匿名、内联、显示声明,这三种方式都要求首先声明angular内置服务(名字一般以$打头)。所有自定义provider的各种非常量形式服务(provider、factory、service)在被注册时会被自动添加"Provider"后缀(三种都是,并非provider添加Provider、factory添加Factory、service添加Service)。
1.推断式依赖注入:参数名必须与服务名一致,angular由此推断需要注入的服务
app.provider('this-service-name', function ($http, $scope, MyOtherService) {})
2.内联:形式:['$builtIn1', '$builtIn2', 'MyOtherService1', function(builtIn1Alias, builtIn2Alias,MyOtherService1Alias){}]
app.provider('this-service-name', ['$builtIn1', '$builtIn2', 'MyOtherService1', function(builtIn1Alias, builtIn2Alias,MyOtherService1Alias){}])
3.显示声明。将依赖声明到对象的$inject数组。var foo=function(){}; foo.$inject = ['$builtIn1', '$builtIn2', 'MyOtherService1']
app.factory('StarFactory', foo)

7.   示例效果及代码

效果如下:

代码压缩包在网盘此处。