angularJS中的核心服务深入理解

 直入正题 

一.constant服务:
app.constant('name',obj)
name为服务的名字,obj为一个json对象.
js:


serviceApp.constant('myConfig',{
    name:'code_bunny',
    age:12,
    getId:function(){
        return 1
    }
});
解析
constant创建服务返回一个json对象(也就是第二个参数中传入的对象),这个对象里可以有参数,可以有方法

,并且,属性和方法都可以在控制器中修改,新增,但是按照它的设计本意,一般constant创建的服务不会去修

改它的内容,需要修改内容,最好用value来创建服务. 

1.它是一个引用对象,无论被注入多少个控制器中,实际都指向同一个对象,所以,无论修改其中的哪一个,其
它所有的服务都会被改变.
2.服务修改过后,ng不会自动同步,简单的说,就是它没有做到自动双向绑定数据,比如在这里给服务新增了
love属性:angular.extend(myConfig,{love:'zxg'}),我需要使用$scope.$watch(myConfig.love,function
(){$scope.love = myConfig.love;})这样才能把love属性值同步到视图中.
3.constant服务不能通过decorator进行装饰,(什么是装饰下面会讲到)
 
二.value服务:
app.value('name',obj)
name为服务的名字,obj为一个json对象.
js:


serviceApp.value('myConfig',{
    name:'code_bunny',
    age:12,
    getId:function(){
        return 1
    }
});


serviceApp.config(function($provide){
    $provide.decorator('myConfig',function($delegate){
        $delegate.money = '100w';
        return $delegate
    })
});
运行结果: http://jsfiddle.net/p0dqr7wy/1/
说明:
value创建服务返回一个json对象(也就是第二个参数中传入的对象),这个对象里可以有参数,可以有方法,并


且,属性和方法都可以在控制器中修改,新增,按照它的设计本意,如果属性和方法需要被修改内容,就用value


来创建服务. 
constant和value主要就是用于存放一些数据或方法以供使用,区别是constant一般是存放固定内容,value存


放可能会被修改的内容
注意点:
1.同constant注意点1
2.同constant注意点2
3.value可以被装饰,所以这里myConfig服务拥有了money属性.(装饰具体怎么用,下面会说)
 
三.factory服务
app.factory('name',function(){return obj})
name为服务的名字,第二个参数传入一个函数,函数需要有一个返回值obj,返回一个对象.实际被注入的服务


就是这个对象.
js:


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
    }
}


装饰部分代码:


serviceApp.config(function($provide){
    $provide.decorator('myConfig',function($delegate){
        console.log($delegate);
        $delegate.money = '100w';
        return $delegate
    })
});


运行结果:
http://jsfiddle.net/8kuxt3xc/
http://jsfiddle.net/ua2y617q/
说明:
factory服务是最常见最常用的服务类型,几乎可以满足90%的自己开发的需求,使用它可以编写一些逻辑,通


过这些逻辑最后返回所需要的对象.比如使用$http来获取一些数据.我们就在factory创建的服务里抓取数据


,最后返回.
它和constant,value最大的区别是,factory服务是有一个处理过程,经过这个过程,才返回结果的. 
注意点:
1.同constant注意点1
2.同constant注意点2
3.factory返回的服务也可以被装饰,所以这里myConfig服务拥有了money属性.(装饰具体怎么用,下面会说)
 
四.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
    }
}


装饰部分代码同上.
运行结果:
http://jsfiddle.net/1qj8m5ot/
http://jsfiddle.net/0bh67cog/
说明:
service和factory的区别在于,它第二个参数传入的是一个构造函数,最后被注入的服务是这个构造函数实例


化以后的结果.所以基本上使用service创建的服务的,也都可以使用factory来创建.
所以这里,factory服务的第二种写法和使用service是一致的:
serviceApp.factory('myConfig',function(){
    return new constructorFun()
});
//等价于
serviceApp.service('myConfig',constructorFun);
注意点:
1.同constant注意点1
2.同constant注意点2
3.service返回的服务也可以被装饰,所以这里myConfig服务拥有了money属性.(装饰具体怎么用,下面会说)
 
五.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
               }
           }
       }
   }
});


装饰部分代码同上.
运行结果: http://jsfiddle.net/2pz2ft73/
说明:
provider服务的第二个参数的返回值中必须要有$get方法(除了$get,还可以有其它方法,后面的例子会说


到),$get方法就相当于factory服务的第二个参数,最后要返回一个对象,这个对象就是真正被注入的服务:
栗子二:
js:


serviceApp.provider('myConfig',function(){
    var id = 1;
    return {
        setID:function(newID){
            id = newID
        },
        $get:function(){
            var myname = 'code_bunny';
            var age = 12;
            return {
                name: myname,
                age: age,
                getId: function(){
                    return id
                }
            }
        }
    }
});
serviceApp.config(function(myConfigProvider){
    myConfigProvider.setID(2)
});


装饰部分代码同上.
运行结果:http://jsfiddle.net/hcpemex3/ 
说明:
这里的provider服务不仅仅返回了$get方法,还返回了setID方法,然后id变量是写在函数里的,返回值的外面


,形成一个闭包,可以被修改.
然后,在provider服务里定义的方法,可以在config函数里调用.注意调用的格式:

如何调用provider定义的服务中的方法:
serviceApp.config(function(myConfigProvider){
    myConfigProvider.setID(2)
});
被注入的服务名不叫myConfig,而是myConfigProvider.然后在函数里面可以调用myConfigProvider的setID


方法(也就是myConfig的setID方法).
通过这种方式,使得我们的服务可以被手动配置,比如这里可以配置id.
ng有很多内置的服务都有这样的功能,比如$route服务,$location服务,当我们通过$routeProvider和


$locationProvider来配置的时候,其本质就是这些服务是通过provider创建的.
注意点:
1.同constant注意点1
2.同constant注意点2
3.provider返回的服务也可以被装饰,所以这里myConfig服务拥有了money属性.(装饰具体怎么用,下面会


说);
 
六.装饰服务
其实通过上面这么多的例子,看也能看懂装饰是什么了...
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服务是不能被装饰的.
栗子就不说了吧,上面的都是~ 
 
总结上面的内容:
1.服务的实例被注入到控制器以后,都是一个引用对象,无论被注入多少个控制器中,实际都指向同一个对象,


所以,无论修改其中的哪一个,其它所有的服务都会被改变.
2.服务的实例被修改过后,ng不会自动同步,需要使用$scope.$watch()监测其变化并手动刷新视图.
3.constant服务不能通过decorator进行装饰.
4.一些固定的参数和方法,使用constant
5.可能被修改的参数和方法,使用value
6.通过逻辑处理后得到的参数或方法,使用factory
7.可以使用factory的也可以使用service,反之亦然(一般就是用factory)
8.可以手动配置参数的服务,使用provider
 
七.可以创建不同实例的服务
之前我们说到,所有的服务的实例都是引用对象,无论被注入多少个控制器中,实际都指向同一个对象,所以,


无论修改其中的哪一个,其它所有的服务都会被改变.这就是ng服务的设计模式,一般不需要去改变,但如果有


特殊需要,要能够每次注入控制器后得到新的实例,可以这样做:
我们给服务添加了一个方法,每次执行一次这个方法,都会创建一个新的实例,这样,虽然在控制器里注入的是


服务实例还是同一个,但是在调用创建实例方法的时候,都会创建一个新的实例,然后就可以单独修改这个实


例,而不会影响到其它控制器:如下
js:


var serviceApp = angular.module('serviceApp',[]);
serviceApp.controller('myCtrl',function($scope,myConfig){
    var myConfigConstant = myConfig.create();
    $scope.name = myConfigConstant.name;
    $scope.age = myConfigConstant.age;
    angular.extend(myConfigConstant,{love:'zxg'});
    $scope.love = myConfigConstant.love;
    $scope.id = myConfigConstant.getId();
    $scope.$watch(myConfigConstant.name,function(){$scope.name = myConfigConstant.name;});
    myConfigConstant.name = 'white_bunny';
});
serviceApp.controller('myOtherCtrl',function($scope,myConfig){
    var myConfigConstant = myConfig.create();
    $scope.love = myConfigConstant.love;
    $scope.name = myConfigConstant.name;
    $scope.$watch(myConfigConstant.name,function(){$scope.name = myConfigConstant.name;});
});




/************************创建实例的服务************************/
serviceApp.factory('myConfig',function(){
    return {
       //服务返回的对象有一个create方法,该方法每次被执行都会返回一个新的constructorFun实例 
    create: constructorFun.createNew
    }
});


//创建一个构造函数
function constructorFun(){
    var myname = 'code_bunny';
    var age = 12;
    var id = 1;
    this.name = myname;
    this.age = age;
    this.id = id
}


//给构造函数添加createNew方法,用于实例化一个constructorFun.
constructorFun.createNew = function(){
    return new constructorFun()
};


//给构造函数添加原型的方法.使得它的实例可以继承.
constructorFun.prototype = {
    getId: function(){
        return this.id
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值