angular 自定义服务

来源:互联网 发布:淘宝店铺 武汉飞鱼运动 编辑:程序博客网 时间:2024/05/29 18:56

    在AngularJS中,我们经常将通用的业务逻辑封装在服务里面,这样一来,不仅减少了代码量,而且使出错率也降低了,代码的易读性也提高了,所以说,我们经常用到了业务逻辑,或者是说持久化数据化操作应该放在自定义的服务里面,而不是Controller里面。下面说一下provider、service、factory的定义方式还有主要区别

1 , factory服务

app.factory('name',function(){return obj})

name为服务的名字,第二个参数传入一个函数,函数需要有一个返回值obj,返回一个对象.实际被注入的服务就是这个对象.

复制代码
serviceApp.factory('myConfig',function(){    var myname = 'code_bunny';    var age = 12;    var id = 1;    return {        name: myname,        age: age,        getId: function(){            return id        }    }});
复制代码

或者是这样:

复制代码
serviceApp.factory('myConfig',function(){    return new constructorFun()});function constructorFun(){    var myname = 'code_bunny';    var age = 12;    var id = 1;    this.name = myname;    this.age = age;    this.getId = function(){        return id    }}
复制代码

用factory 就是创建一个对象,为它添加属性,然后把这个对象返回出来。

factory服务是最常见最常用的服务类型,几乎可以满足90%的自己开发的需求,使用它可以编写一些逻辑,通过这些逻辑最后返回所需要的对象.比如使用$http来获取一些数据.我们就在factory创建的服务里抓取数据,最后返回.

它和constant,value最大的区别是,factory服务是有一个处理过程,经过这个过程,才返回结果的. 

2 , service服务

app.service('name',constructor)

name为服务的名字,constructor是一个构造函数.

js:

复制代码
serviceApp.service('myConfig',function(){    var myname = 'code_bunny';    var age = 12;    var id = 1;    this.name = myname;    this.age = age;    this.getId = function(){        return id    }});
复制代码

或者是这样:

复制代码
serviceApp.service('myConfig',constructorFun);function constructorFun(){    var myname = 'code_bunny';    var age = 12;    var id = 1;    this.name = myname;    this.age = age;    this.getId = function(){        return id    }}
复制代码

service和factory的区别在于,它第二个参数传入的是一个构造函数,最后被注入的服务是这个构造函数实例化以后的结果.所以基本上使用service创建的服务的,也都可以使用factory来创建.

所以这里,factory服务的第二种写法和使用service是一致的:

serviceApp.factory('myConfig',function(){    return new constructorFun()});
//等价于serviceApp.service(
'myConfig',constructorFun);


3,provider服务

复制代码
app.provider('name',function(){  ....  return {    ...    $get:function(){      ...      return obj    }     }})
复制代码

name为服务的名字,第二个参数接受一个函数,函数返回一个对象,返回的对象比如要有$get方法,$get方法必须要返回一个对象obj,这个对象就是真正被注入的服务.

栗子一:

js:

复制代码
serviceApp.provider('myConfig',function(){   return {       $get:function(){           var myname = 'code_bunny';           var age = 12;           var id = 1;           return {               name: myname,               age: age,               getId: function(){                   return id               }           }       }   }});
复制代码
provider服务的第二个参数的返回值中必须要有$get方法(除了$get,还可以有其它方法,后面的例子会说到),$get方法就相当于factory服务的第二个参数,最后要返回一个对象,这个对象就是真正被注入的服务:


Providers是唯一 一种你可以传进 .config() 函数的service。(provider,factory,service

在provider服务里定义的方法,可以在config函数里调用.注意调用的格式:

serviceApp.config(function(myConfigProvider){    myConfigProvider.setID(2)});

被注入的服务名不叫myConfig,而是myConfigProvider.然后在函数里面可以调用myConfigProvider的setID方法(也就是myConfig的setID方法).

通过这种方式,使得我们的服务可以被手动配置,比如这里可以配置id.

ng有很多内置的服务都有这样的功能,比如$route服务,$location服务,当我们通过$routeProvider和$locationProvider来配置的时候,其本质就是这些服务是通过provider创建的.


补充:

(1),装饰

app.config(function($provide){    $provide.decorator('name',function($delegate){          $delegate.money = '100w';           return $delegate    })});

同样是通过config,在参数函数中注入$provider服务,$provider服务有个decorator方法,它接受两个参数,第一个参数'name',是要被装饰的服务的名字,第二个参数是一个函数,函数中注入$delegate,$delegate就是被装饰的服务的实例,然后在函数中操作$delegate,就相当于操作了该服务的实例.

注意:

1.最后一定要return $delegate,这样服务才算被装饰完成了.

2.constant服务是不能被装饰的.

(2),$watch:持续监听数据上的变化,更新界面,(两个controller用同一个实例对象  每个控制器都需要$watch 数据才会更新

$scope.$watch(myConfig.love,function(){$scope.love = myConfig.love;});

复制代码
var serviceApp = angular.module('serviceApp',[]);serviceApp.controller('myCtrl',function($scope,myConfig){    $scope.name = myConfig.name;    $scope.love = myConfig.love;    $scope.age = myConfig.age;    $scope.money = myConfig.money;    $scope.id = myConfig.getId();    $scope.$watch(myConfig.love,function(){$scope.love = myConfig.love;});
})
serviceApp.controller(
'myOtherCtrl',function($scope,myConfig){ $scope.name = myConfig.name; $scope.love = myConfig.love; angular.extend(myConfig,{love:'zxg'}); $scope.$watch(myConfig.love,function(){$scope.love = myConfig.love;});});
复制代码

(3),constant:

app.constant('name',obj)

name为服务的名字,obj为一个json对象.

constant服务不能通过decorator进行装饰

constant创建服务返回一个json对象(也就是第二个参数中传入的对象),这个对象里可以有参数,可以有方法,并且,属性和方法都可以在控制器中修改,新增,但是按照它的设计本意,一般constant创建的服务不会去修改它的内容,需要修改内容,最好用value来创建服务. 


(4),value服务:

app.value('name',obj)

name为服务的名字,obj为一个json对象.

value创建服务返回一个json对象(也就是第二个参数中传入的对象),这个对象里可以有参数,可以有方法,并且,属性和方法都可以在控制器中修改,新增,按照它的设计本意,如果属性和方法需要被修改内容,就用value来创建服务. 

constant和value主要就是用于存放一些数据或方法以供使用,区别是constant一般是存放固定内容,value存放可能会被修改的



总结上面的内容:

1.服务的实例被注入到控制器以后,都是一个引用对象,无论被注入多少个控制器中,实际都指向同一个对象,所以,无论修改其中的哪一个,其它所有的服务都会被改变.

2.服务的实例被修改过后,ng不会自动同步,需要使用$scope.$watch()监测其变化并手动刷新视图.

3.constant服务不能通过decorator进行装饰.

4.一些固定的参数和方法,使用constant

5.可能被修改的参数和方法,使用value

6.通过逻辑处理后得到的参数或方法,使用factory

7.可以使用factory的也可以使用service,反之亦然(一般就是用factory)

8.可以手动配置参数的服务,使用provider