zoukankan      html  css  js  c++  java
  • 【AngularJS】—— 13 服务Service

    在AngularJS中有很多的服务,常用的比如http,location等等。

    本篇文章会介绍一下的内容:

      1 $http这种Angular提供的服务的使用

      2 如何自定义服务,并总结服务需要注意的几个小点。

      $http的使用

      AngularJS为我们提供了很多种服务,$http用于发送http请求,动态的请求数据。

      这样就需要使用web容器来运行代码了,先看看程序源码,视图方面还是跟普通的代码相同:

    <div ng-controller="myAppCtrl">
                <ul>
                    <li ng-repeat="user in users">
                        {{user.name}}
                    </li>
                </ul>
            </div>

      创建一个无序列表,循环输出请求到的数据。

      在js中,创建一个模板,在模板上创建控制器。

    <script type="text/javascript">
                var myAppModule = angular.module("myApp",[]);
    
                myAppModule.controller('myAppCtrl',['$scope','$http',function($scope,$http){
                    $http({
                        method:'GET',
                        url:'data.json'
                    }).success(function(data,status,headers,config){
                        console.log("success!...");
                        console.log(data);
                        $scope.users = data;
                    }).error(function(data,status,headers,config){
                        console.log("error!...");
                    });
                }]);
            </script>

      该控制器比平时普通的控制器多了一个注入的参数$http,添加了这个参数,就可以在方法内部直接调用。

      采用如下的格式:

    $http({
      method:'GET',//http请求的类型
      url:'data.json'//请求的地址
    }).success(function(data,status,headers,config){
      //成功了,怎么做
    }).error(function(data,status,headers,config){
      //失败了,怎么做
    });

      接下来需要在代码相同的路径下,创建data.json文件

    [{
        "name":"test1"
    },{
        "name":"test2"
    },{
        "name":"test3"
    }]

      利用web容器,本文使用的是基于nodejs的http-server,启动后在网页中输入相应的URL查看结果:

      全部的代码展示:

    <!doctype html>
    <html ng-app="myApp">
        <head>
             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
             <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
        </head>
        <body>
            
            <div ng-controller="myAppCtrl">
                <ul>
                    <li ng-repeat="user in users">
                        {{user.name}}
                    </li>
                </ul>
            </div>
    
            <script type="text/javascript">
                var myAppModule = angular.module("myApp",[]);
    
                myAppModule.controller('myAppCtrl',['$scope','$http',function($scope,$http){
                    $http({
                        method:'GET',
                        url:'data.json'
                    }).success(function(data,status,headers,config){
                        console.log("success!...");
                        console.log(data);
                        $scope.users = data;
                    }).error(function(data,status,headers,config){
                        console.log("error!...");
                    });
                }]);
            </script>
        </body>
    </html>
    View Code

      使用$http是很基本的内容,就不做过多的解释了。

      创建自己的Service服务

      接下来看看如何创建自己的服务,创建服务可以通过三种方式,factory,provider和service,但是它们的本质都是Provider,只是封装了不同的写法而已。

      本文采用factory的形式,仍然是先创建一个模块,在模块的基础上创建一个Service:

    var myAppModule = angular.module("myApp",[]);
    
                myAppModule.factory('myService',['$http',function($http){
                    var doRequest = function(username){
                        return $http({
                            method:'GET',
                            url:'data.json'
                        });
                    }
                    return {
                        userList:function(username){
                            return doRequest(username);
                        }
                    }
                }]);

      分析下代码:

      这个Service需要注入一个属性 $http ,在方法内部,返回的值是一个对外提供的方法,userList。

      外部可以通过 userList(username) 的方式,进行调用。

      真正的实现部分放在 doRequest 中,内部就是典型的一个AngularJS的$http请求了,请求会返回url相应的数据。

      然后看一下外部如何使用,先看看视图部分:

            <div ng-controller="myAppCtrl">
                <label>username</label>
                <input type="text" ng-model="username" placeholder="输入"/>
                <pre ng-show="username">
                    {{users}}
                </pre>
            </div>

      该部分是一个输入框input和一个代码框pre,他们共同使用了一个变量username。当username有值时,会在下面展示users对应的内容。

    myAppModule.controller('myAppCtrl',['$scope','$timeout','myService',
                    function($scope,$timeout,myService){
                        var timeout;
                        $scope.$watch('username',function(newUserName){
                            console.log("您输入了:"+newUserName);
                            if(newUserName){
                                if(timeout){
                                    $timeout.cancel(timeout);
                                }
                                timeout = $timeout(function(){
                                    myService.userList(newUserName).success(function(data){
                                        console.log(data);
                                        $scope.users = data;
                                    });
                                },350);
                            }
                        });
                    }
                ]);

      在对应的控制器中,采用了$watch这种监控方法,监控username属性的变化。当username属性变化时,会触发请求方法。

      控制器多注入了一个$timeout变量,该变量用于控制输入的时间。代码观察$timeout(function(...),350);当输入的间隔超过350ms时,就会触发相应函数function(...)。这样可以有效的防止,不停的刷新请求,造成网页的刷新抖动。

      在函数内部,调用了我们自己的服务提供的userList方法。当请求成功时,绑定返回值到users中。users会动态的刷新内容。

      查看程序的演示结果:

      通过测试发现:当我们快速的输入4321时,虽然$watch都监控到了变量的变化,但是只有停止时间超过350ms才会发送请求。

      全部的代码样例:

    <!doctype html>
    <html ng-app="myApp">
        <head>
             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
             <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
        </head>
        <body>
            
            <div ng-controller="myAppCtrl">
                <label>username</label>
                <input type="text" ng-model="username" placeholder="输入"/>
                <pre ng-show="username">
                    {{users}}
                </pre>
            </div>
    
            <script type="text/javascript">
                var myAppModule = angular.module("myApp",[]);
    
                myAppModule.factory('myService',['$http',function($http){
                    var doRequest = function(username){
                        return $http({
                            method:'GET',
                            url:'data.json'
                        });
                    }
                    return {
                        userList:function(username){
                            return doRequest(username);
                        }
                    }
                }]);
    
                myAppModule.controller('myAppCtrl',['$scope','$timeout','myService',
                    function($scope,$timeout,myService){
                        var timeout;
                        $scope.$watch('username',function(newUserName){
                            console.log("您输入了:"+newUserName);
                            if(newUserName){
                                if(timeout){
                                    $timeout.cancel(timeout);
                                }
                                timeout = $timeout(function(){
                                    myService.userList(newUserName).success(function(data){
                                        console.log(data);
                                        $scope.users = data;
                                    });
                                },350);
                            }
                        });
                    }
                ]);
            </script>
        </body>
    </html>
    View Code

      关于自定义的服务,有下面几点需要注意:

      1 它的使用场景:由于可以在服务中抽取公共调用的方法,因此可以把多个控制器中相同的功能抽取出来,形成一个服务。

      2 单例:服务都是单例的,一个应用生命周期内,只有一个服务的实例存在。

      3 注入器:服务的实例化都是有注入器injector创建的。在我们创建controller控制器时,后面指明了需要注入一个myService服务,注入器就会去实例化该服务。

      参考

      [1] 大漠穷求,慕课网:http://www.imooc.com/learn/156

  • 相关阅读:
    NSPrediccate 查询
    集合 不可变集合
    集合 不可变
    考核题 7
    考核题 6
    考核题 4
    练习题12
    练习题3
    iOS 实现在string任意位置添加新的表情
    在 ZBarSDK 中使用Block回调传值 Block在扫描成功后 变为空
  • 原文地址:https://www.cnblogs.com/feng18/p/5137197.html
Copyright © 2011-2022 走看看