美文网首页我爱编程
AngularJS:Service、Factory、Provid

AngularJS:Service、Factory、Provid

作者: 阿羡吖 | 来源:发表于2018-03-16 15:28 被阅读0次

    本篇转载于:http://blog.csdn.net/evankaka
    AngularJs GitHub: https://github.com/angular/angular.js/
    AngularJs下载地址:https://angularjs.org/
    注:代码都亲测过,效果是一样的,所以用了作者原本的图,望谅解

    AngularJs中可用来注入的有三种类型,service、factory、provide,这三种写法不一样,用法也不一样,其中,service只实例化一次,其实就是单例模式的思想,无论我们在什么地方注入service,将永远使用同一个实例,所以对很多Controller的操作就可以放到service层中去。
    AngularJS提供例如许多的内在服务,如:$http$route$window,$location等等。每个服务负责例如一个特定的任务,$http是用来创建AJAX调用,已获得服务器的数据。$route用来定义路由信息等。内置的服务总是前缀$符号。
    关系图如下所示:

    image.png

    一、Service使用详解
    (1)定义
    一般使用this来操作数据、定义函数。

    app.service('myService', function () {
        var privateValue='I am priivate';
        this.variable = 'This is public';
        this.getPrivate = function(){
            return privateValue;
        };
    });
    

    (2)AngularJS中使用DI添加Service的三种方式
    方式1(内联注解,推荐使用)

    app.controller('myController',['$scope','deteFiler',function($scope,deteFilter){}]);
    

    方式2($inject注解)

    var MyController = function($scope,dateFilter){}
    MyController.$inject =['$scope','dateFilter'];
    someModule.controller('MyController',MyController);
    

    方式3 (隐式注解、不推荐使用);

    app.controller('mycontroller',function($scope,dateFilter){});
    

    推荐使用方法1的理由是:
    写法上比方法2更简单明了,比方法3更可靠(由于JavaScriptkeyi可以被压缩,AngularJs又是通过解析服务器名称找到对应的Service的,因为JavaScript压缩之后AngularJs将无法找到指定的Service,但字符串不会被压缩,因此单独以字符串指定的Service的名称可以避免这个问题)
    使用方法1或方法2的注意点:
    由于上述第二点原因:AngularJS在编译Htm时,由$injector将数组中的service的名称与方法中的Service进行--映射。这种映射关系必须遵循由AngularJS的约定:
    数组中Service名称的个数必须与方法体中Service名称个数一致
    数组中Service的顺序必须与方法体中Service的顺序一致。

    (3)什么时候适合使用Service()方法
    Service()方法很适合使用在功能控制比较多的Service()里面
    *需要使用.config()来配置service的时候不能使用service()方法
    (4)service使用实例

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp">
    <head>
        <meta charset="UTF-8">
        <title>AngularJs学习</title>
        <script type="text/javascript" src="js/angular.min.js"></script>
    </head>
    <body>
        <div ng-controller="MyCtrl">
            <button ng-click="getPrivate()">按钮一</button>
            <button ng-click="getPublic()">按钮二</button>
        </div>
        <div ng-controller="MyCtrl2"></div>
    </body>
    <script type="text/javascript">
        var app = angular.module('myApp', []);
        app.controller('MyCtrl',function ($scope,myService) {
            $scope.getPrivate = function(){
                alert(myService.getPrivate());
            };
            $scope.getPublic = function(){
                alert(myService.variable);
            };
        });
        app.controller('MyCtrl2',function ($scope,myService) {  
        });
        app.service('myService', function () {
            console.log('instance myService');
            var privateValue = 'I am private';
            this.variable = 'This is public';
            this.getPrivate=function(){
                return privateValue;
            }
        });
    </script>
    </html>
    

    效果如下:

    image.gif
    另外,从控制台可以看出两个Controller注入了同一个Service,但最终只实例化了一次。
    image.png
    service定义的服务不能在.config中使用!只有providerdingyi定义的才可以

    二、Factory使用详解
    Factory一般就是创建一个对象。然后在这个对象添加方法与数据,最后将些对象返回即可,然后注入到Controller层中即可。
    使用实例:

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp">
    <head>
        <meta charset="UTF-8">
        <title>AngularJs学习</title>
        <script type="text/javascript" src="js/angular.min.js"></script>
    </head>
    <body>
        <div ng-controller="MyCtrl">
            <button ng-click="getPrivate()">按钮一</button>
            <button ng-click="getPublic()">按钮二</button>
        </div>
        <div ng-controller="MyCtrl2"></div>
    </body>
    <script type="text/javascript">
        var app = angular.module('myApp', []);
        app.controller('MyCtrl',function ($scope,myFactory) {
            $scope.getPrivate = function(){
                alert(myFactory.getPrivate());
            };
            $scope.getPublic = function(){
                alert(myFactory.variable);
            };
        });
        app.controller('MyCtrl2',function ($scope,myFactory) {  
        });
        app.factory('myFactory', function () {
            console.log('instance myFactory');
            var privateValue = 'I am private';
            this.variable = 'This is public';
            this.getPrivate=function(){
                return privateValue;
            };
            return factory;
        });
    </script>
    </html>
    

    效果如下:


    image.gif

    另外,从这里可以看到controller注入同一个factory,但是最终只实例化了一次。


    image.png
    记住一定要return 一个Object对象,否则会报出一下错误。
    image.png

    三、provider使用详解
    $provide服务负责告诉AngularJs如何r创造一个新的可注入的东西,即服务。服务会被叫做供应商的东西来定义,你可以使用$provide来创建一个供应商。你需要使用$provide中的provider()方法来定义一个供应商,同时也可以通过要求$provide被注入到一个引用的config函数中来获得$provide服务,使用方法是返回一个$get函数,注意的是,在config阶段,只有provider能被注入,其他用法和service一样。
    实例:

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp">
    <head>
        <meta charset="UTF-8">
        <title>AngularJs学习</title>
        <script type="text/javascript" src="js/angular.min.js"></script>
    </head>
    <body>
        <div ng-controller="myCtrl1">
            <button ng-click="onclick1()">请点击我1</button>
        </div>
        <div ng-controller="myCtrl2">
            <button ng-click="onclick2()">请点击我2</button>
        </div>
    </body>
    <script type="text/javascript">
        var app = angular.module('myApp', []);
        app.controller('myCtrl1', function ($scope , testProvider) {
            $scope.onclick1=function(){
                testProvider("林炳文Evankaka");
            };
        });
    
        app.controller('myCtrl2',function ($scope , testProvider) {
            $scope.onclick2 = function(){
                testProvider("我到底是谁");
            };
        });
    
        app.provider('testProvider', function () {
            console.log('instance testProvider');
            var f = function(name){
                alert("hello,"+name);
            }
            this.$get = function() {
                return f;
            };
        });
    </script>
    </html>
    

    效果如下:


    image.gif

    控制台输出内容:


    image.png

    下面是一个provider实例化的时间测试

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp">
    <head>
        <meta charset="UTF-8">
        <title>AngularJs学习</title>
        <script type="text/javascript" src="js/angular.min.js"></script>
    </head>
    <body>
        <div ng-controller="myCtrl1">
            <button ng-click="onclick1()">请点击我1</button>
        </div>
        <div ng-controller="myCtrl2">
            <button ng-click="onclick2">请点击我2</button>
        </div>
    </body>
    <script type="text/javascript">
        var app = angular.module('myApp', []);
    
        app.controller('myCtrl1',function ($scope) {
            // $scope.onclick1 = function(){
            //  test("林炳文Evankaka");
            // };
        });
        app.controller('myCtrl2', function ($scope) {
            // $scope.onclick2 = function(){
            //  test("我到底是谁");
            // };
        });
    
        // app.config(function (testProvider) {
        //  testProvider('I am config');
        // });
    
        app.provider('test', function () {
            console.log('instance test')
            var f = function(name){
                alert("hello,"+name);
            }
    
            this.$get = function() {
                return f;
            };
        });
    
        app.config(function ($provide) {
            $provide.provider('greetting', function(){
                this.$get = function(){
                    return function(name){
                        alert('hello,'+name);
                    }
                }
            });
            // greetingProvider('ff');
        });
    </script>
    </html>
    
    image.png

    页面刷新后,即使不注入provider,但它也进行了实例化,而Service/Factory则是第一次注入时才会初始化。而这也是为什么它可以注入到config的一个原因吧。

    什么时候使用provider() 方法
    (1)当我们希望在应用开始前对Service进行配置的时候就需要使用到provider().。比如,我们需要配置Service在不同的部署环境(开发,演示,生产)使用不同的后端处(2)理的时候,就可以使用到了,当我们打算发布开源provider()也是首选创建service的方法,这样就可以使用配置的方法来配置Services而不是将配置数据硬编码写到代码里。

    四、Service、Factory、Provider三者的区别

    (1)用Factory就是创建一个对象,为它添加属性,然后把这个对象返回出来。把Service传进Controller之后,在Controller里这个对象的属性就可以通过factory使用了。
    (2)Service是用new关键字实例化的。因此,应该给this添加属性。然后service返回this,把service传进Controller之后,在Controller里this上的属性就可以通过Service来使用了。
    (3)providers是唯一一种可以传入.config()函数的Service。当想要在Service对象启用之前,先进性模块范围的配置,那就应该使用provider
    (4)Factory/service是第一个注入时才实例化。而provider不是,它是在config之前就实例化好了。
    同一种函数的三种不同写法:

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp">
    <head>
        <meta charset="UTF-8">
        <title>AngularJs学习</title>
        <script type="text/javascript" src="js/angular.min.js"></script>
    </head>
    <body>
        <div ng-controller="myCtrl1">
            <p>{{ output1 }}</p>
            <p>{{ output2 }}</p>
            <p>{{ output3 }}</p>
        </div>
        <div ng-controller="myCtrl2"></div>
    </body>
    <script type="text/javascript">
        var app = angular.module('myApp', []);
        app.controller('myCtrl1', function ($scope,testService,testFactory,testProvider) {
            $scope.output1 = testService.lable;
            $scope.output2 = testFactory.lable();
            $scope.output3 = testProvider;
        });
    
        app.controller('myCtrl2', function ($scope,testService,testFactory,testProvider) {
            
        });
    
        app.service('testService', function () {
            console.log('instance testService');
            this.lable = 'this is service'; 
        });
    
        app.factory('testFactory', function () {
            console.log('instance testFactory');    
        
            return {
                lable:function(){
                    return 'this is factory';
                }
            };
        });
    
        app.provider('testProvider', function () {
            console.log('instance testProvider');
            
            this.$get = function() {
                return 'this is provider';
            };
        });
    </script>
    </html>
    
    image.png

    看console的输出,可以知道都只实例 化了一次:


    image

    相关文章

      网友评论

        本文标题:AngularJS:Service、Factory、Provid

        本文链接:https://www.haomeiwen.com/subject/jymcqftx.html