Angular的服务介绍

AngularJS与服务端交互

  • 简介

    在Angular框架中的内部,封装了许多的服务模块,供开发者与服务端交互时调用。如$http$resource等众多的服务。同时,应用内部的缓存机制可加速交互时的数据通信,通过$resource服务快速响应服务端的RESTful方式的资源请求,高效地处理客户端与服务端间的数据交互。

  • 与服务端交互介绍

    使用javascript代码,需要实现与服务端的数据通讯,那么,我们会使用AJAX方式,初始化XHR对象,调用对象的send方法发送数据请求,并以异步的方式获取请求返回内容,angular中的$http服务则是将这种方法进行了简单的封装,打包成一个服务模块的形式提供开发者使用。

    • 传统的AJAX方式与服务端交互

    • 介绍

      js 代码中我们可以通过XHR对象中的send方法向服务端发送请求,而这里的XHR对象是XMLHttpRequest对象的缩写,改对象目前在各个主流浏览器中都支持,在低版本的的ie6以下的浏览器中只支持ActiveXObject对象来代替它,因此,在使用XHR对象时,需要注意的是兼容性的写法。

    • 代码

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="components/angular/angular.min.js"></script>
      </head>
      
      <body>
        <ul id="studentList">
            <li>正在载入...</li>
        </ul>
        <script>
            (function () {
                console.log(2);
                var xhr = null;
                if (window.ActiveXObject) {
                    xhr = new ActiveXObject("Microsoft.XMLHTTP");
                } else {
                    console.log(3);
                    xhr = new XMLHttpRequest();
                }
                xhr.onreadystatechange = function(){
                    if (xhr.readyState == 4) {
                    console.log(1);
                    if (xhr.status == 200) {
                        var html = "";
                        console.log(xhr.responseText);
                        var data = eval("(" + xhr.responseText + ")");
                        console.log(data);
                    }
                }
                }    
                xhr.open("GET", "lib/stu.php", true);
                xhr.send();
            })()
        </script>
      </body>
      
      </html>
      <?php
      header("Content-type: text/json");
      
      $stulist = array(
        array("code"=>"001","Name"=>"devid"),
        array("code"=>"002","Name"=>"liming"),
        array("code"=>"003","Name"=>"zs"),
        array("code"=>"004","Name"=>"ls"),
      );
      // echo header("Access-Control-Allow-Origin:*");  
      echo json_encode($stulist);
      
      ?>
    • 说明

      • 定义xhr对象,针对不通的浏览器
      • 调用xhr对象的open方法,初始化HTTP请求,再通过send方法向服务端发送初始化后的HTTP请求
      • 绑定xhr对象的onreadystatechange。这个是异步时间,可以时刻观察xhr发送请求之后的readyState状态值,为 4 代表请求成功,responseText属性就是服务端的返回体。
    • 使用$http快捷方式与服务端交互

    • 介绍

      • 说明:调用$http服务模块,该模块底层封装了XMLHttpRequest对象

      • 接收一个对象作为参数,用于收集生成HTTP请求的配置内容

      • 返回一个promise对象,该对象拥有名为success和error的两个回调函数

      • 调用方式:

      $http.请求类型(url,[data],[config])
          .success(data,status,headers,config){
              //成功之后的操作
          }
          .error(data,status,headers,config){
              //失败之后的操作
          }
      e.g.
      $http.post(url,data,{headers:'',transformRequest:function(obj){},timeout:''})
          .success(data,status,headers,config){
              //成功之后的操作
          }
          .error(data,status,headers,config){
              //失败之后的操作
          }
      • 参数介绍

      • url:代表着一个相对会着绝对的服务器请求路径

      • 请求类型
        • post:可以通过可选参数data来发送数据,除发送数据外还可以通过选项参数config来设置请求时传递的数据。
        • get
        • jsonp
        • delete
        • put:可以通过可选参数data来发送数据,除发送数据外还可以通过选项参数config来设置请求时传递的数据。
        • head
      • 请求成功之后

        • 回调success方法中获取服务端返回的数据和相关信息。
        • 回调函数的参数
        • data:返回体,请求返回的结果集
        • status:请求后返回的状态值
        • headers:表示请求后返回的头函数
        • config:一个对象,可以获取发送HTTP请求时完整的配置信息。
      • 代码举例

      <html>
      <body ng-app="myApp" ng-controller="myCtrl" >
      .....
      </body>
      <script>
           var myApp = angular.module('myApp',[])
           .controller('myCtrl',funtion($scope,$http){
                       $http.post(
        //url
              url,
        //data,{user_name: "admin", user_password: "admin", user_language: "ZHS"}
              data,
        //config
               {
                transformRequest: function (obj) {
                  var str = [];
                  for (var p in obj) {
                    str.push(encodeURIComponent(p) + "=" +                                        encodeURIComponent(obj[p]));
                  }
                  return str.join("&");
                },
                headers: {
                  'Content-Type': 'application/x-www-form-urlencoded'
                },
                timeout: 15000
              }
            )
            .success(function (data, status, headers, config) {
              ...
            })
            .error(function (data, status, headers, config) {
              ...
      })
                       })
      
      </script>
      <html>
      • 说明
        • config中,transformRequest函数,对HTTP发送的内容进行转吗,并对转码后的内容进行操作,便于发送时的数据传送和服务端的接收
        • 由于是POST数据请求,因此,还必须将请求头信息中的Content-Type属性值置为“application/x-www-form-urlencoded”,编码格式,不然无法将客户端的数据以post方式发送给服务器。
      <html>
      <body ng-app="myApp" ng-controller="myCtrl" >
      .....
      </body>
      <script>
          var myApp = angular.module('myApp',[])
          .controller('myCtrl',funtion($scope,$http){
                      $http.post(
              //url
                  url,
              //data,对象类型
                  '_request_data=' + encodeURIComponent($filter('json')({parameter: para})),
              //config
                  {headers: {'Content-Type': 'application/x-www-form-urlencoded'},timeout: 15000}
          )
            .success(function (data, status, headers, config) {
                  ...
            })
            .error(function (data, status, headers, config) {
                  ...
              })
                      })
      
      </script>
      <html>
      • 说明:
        • ’_request_data=’ + encodeURIComponent($filter(‘json’)({parameter: para})), 与transformRequest函数的效果是一样的。
      <html>
      <body ng-app="myApp" ng-controller="myCtrl" >
      .....
      </body>
      <script>
          var myApp = angular.module('myApp',[])
              .config(function($httpProvider){
                  $httpProvider.defaults.transformRequest = function(obj){
                      var str = [];
                      for(var p in obj){
                          str.push(encodeURIComponent(p) + "=" +                                      encodeURIComponent(obj[p]));
                      }
                  return str.join("&");
              })
                   $httpProvider.defaults.headers.post= {'Content-Type': 'application/x-www-form-urlencoded'}    
                  .controller('myCtrl',function($scope,$http){
                      $http.post(
                      //url
                          url,
                      //data,对象类型
                          data,
                      //config
                          {headers: timeout: 15000}
                  )
                      .success(function (data, status, headers, config) {
                          ...
                      })
                      .error(function (data, status, headers, config) {
                          ...
                      })
                  })
      </script>
      <html>
      • 说明
        • 调用config方法,注入$httpProvider服务,并调用该服务对象重置发送数据时的默认函数,transformRequest和Content-Type值
    • 使用$http配置对象方式与服务端交互

    • 调用格式

      $http({
        method:
        url:
        data:
        params:
        transformQuest:
        transformResponse:
        cache:
        timeout:
      })
    • 参数介绍

      method:请求方式,post,get,JSONP,DELETE,PUT,HEAD
      url:表示服务器请求的地址,是一个相对的绝对的字符串形式。
      data:一个对象,该对象将作为消息体的一部分发送给服务端,常用于POST和PUT数据时使用。
      params:属性使用一个字符串或对象,当发送HTTP请求的时候,如果是对象,将自动按照json格式进行序列化,并追加到URL后面作为发送数据的一部分,传递给服务器。
      transformRequest:用于对请求体头信息和请求体进行序列化转换,并生成一个数组发送给服务端
      transformResponse:用于对于响应体头信息和响应体进行反序列化的转换,就是解析服务器发送来的的被序列化的数据。
      cache:是否对http请求返回的数据进行缓存,如果改制为true,表示需要缓存,否则不缓存
      timeout:后者表示延迟发送HTTP请求的时间,单位为毫秒。

  • Angular中的缓存

    • 介绍

    • 核心组成是一个个键key/值value存储集合

    • 一个键对应一块缓存内容
    • 键值存在有效才能通过键值返回对应的缓存内容
    • $cacheFactory来生成缓存对象,
    • $http服务中还可以开启缓存

    • $cacheFactory服务创建缓存对象

    • 创建缓存对象

      $cacheFactory(key,[options])

      说明:key表示缓存对象的名称,可选项参数options是一个对象,用于指定缓存的特征。通常情况下,将在这个对象中添加一个capacity属性,它是一个数字,用于说明缓存的最大容量。如果值为3的话,表示只能缓存前三次请求,进入第4次时,自动将使用最少的内容从缓存中删除

    • 通过get方法访问指定键名的缓存对象

      $cacheFactory.get(key);
    • info方法

      • 介绍

      info方法返回缓存对象的信息,大小,名称

      • 使用
      var cache = $cacheFactory("test");
      console.log(cache.info());
      //输出:Object{id:"test",size:0}
    • put

      • 介绍

      put方法可以向缓存对象中以key/value的形式添加缓存内容,整个方法还将返回添加后的键值

      • 使用
      cache.put("c1","hello");
      console.log(cache.put("c1","hello"));
      //输出:hello
    • get方法

      • 介绍

      get方法可以获取键名对应的键值内容

      • 使用
      console.log(cache.get('c1'));// hello
      console.log(cache.get('c2')); // undefined
    • remove方法

      • 介绍

      remove方法可以移除指定键名的缓存

      • 使用
      cache.remove("c1");
      console.log(cache.get("c1")); //undefined
    • removeAll和destory方法

      • 介绍
      • removeAll方法用于移除全部的缓存对象,并重置缓存结构。
      • destory方法则是从$cacheFactory缓存注册表中删除所有的缓存引用条目,并重置缓存对象。
    • $http服务中的缓存

    • 自定义$http服务中的缓存

  • $resource服务

    • 介绍

    • 支持RESTful的服务器进行无缝隙的数据交互。数据模型方式的对接

    • 无需编写大量代码便可以实现许多复杂的功能

    • $resource服务使用和对象中的方法

    • 代码引入

      <script src="../angular-resource.min.js></script>
    • 在应用模型中注入

      angular.module('myApp',['ngResource'])    
    • 调用$resource服务

      var obj = $resource(url,[,paraDefaults][,actions]) 
      • url:请求服务器的地址,其中允许占位符变量,该变量必须以“:”为前缀
      var obj = $resource('url?action:act');
      //向服务器发送的实际地址就为“url?action=save”  占位符
      obj.$save{act:'save'}

      • paramDefaults是一个对象,用于设置请求时的默认参数,在发送请求时,该对象的全部值将自动进行序列化,如果遇到占位符自动替换,并将结果添加到url请求之后
      var obj = $resource('url?action=act',{
          act:'save',
          a:'1',
          b:'2'
      })
      //url?action=save&a=1&b=2
      • actions:对象,扩展默认资源动作
      var obj = $resource('url?action=:act',{
          //定义请求默认值
      },{
          a:{
              method:'get'
          }
      })
      
    • $resource对象中的GET类型请求

      • $resource对象中GET类型的请求有两个,分别是get和query,他们的调用格式如下:
      var obj = $resource('url');
      //get()方法
      obj.get(params,successFn,errorFn);
      //query()方法
      obj.query(params,successFn,errorFn);
      • 参数说明:
      • Params:是一个对象,用于添加请求一起发送的数据,请求时,该对象中的键值将自动进行序列化并添加到url的后面。
      • successFn:参数表示请求成功后的回调函数
      • errorFn:参数表示请求失败后回调函数
    • $resource对象中非给类型请求

      • $resource对象中,3个非GET类型的请求,分别为save,delete和remove,调用格式如下:
      var obj = $resource('url');
      //save()方法
      obj.save(params,postDate,successFn,errorFn);
      //delete();方法
      obj.delete(params,postDate,successFn,errorFn);
      //remove方法
      obj.remove(params,postDate,successFn,errorFn);
      • 参数说明

      • Params:是一个对象,用于添加请求一起发送的数据,请求时,该对象中的键值将自动进行序列化并添加到url的后面。

      • successFn:参数表示请求成功后的回调函数
      • errorFn:参数表示请求失败后回调函数
      • postdata:该参数是一个对象,是为了让添加以非get方式想服务端发送的数据体。

      • 具体介绍:

      • save方法:

        在服务端保存数据时使用。执行的时候,以POST方式向服务端发送一个请求,postData参数中添加的数据体也将一起被发送

      • delete和remove方法都是在删除服务端数据时使用。执行时将携带postData参数中添加的数据体,以delete的方式向服务端发送一个请求,两者的区别在于,remove解决了在ie浏览器中delete是js保留字段而导致的错误问题。

    • 在$resource服务中自定义请求方法

  • promise对象

    • promise的基本概念和使用方法

    • 基础概念

      通过$q对象调用defer方法创建一个延期对象,调用promise属性创建一个promise对象

    • 使用方法

      • notify():发送消息
      • resolve():解决
      • reject():拒绝
      • when():没有创建延期对象,调用when方法。
    • 代码举例:

      var defer = $q.defer();
      var promise = defer.promise;
      promise.then(successCallback,errorCallBack,notifyCallback)

    • promise对象的创建和使用

    • 代码举例

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>promise对象</title>
        <script src="components/angular/angular.min.js"></script>
        <style>
        </style>
      </head>
      <body ng-app="a4_1">
        <div ng-controller="c4_1">
           <div>
               <div>{{t0}}</div>
               <div>{{t1}}</div>
               <button ng-click="action(true)">解决</button>
               <button ng-click="action(false)">拒绝</button>
           </div> 
        </div>
        <script>
            var a4_1 = angular.module('a4_1',[]);
                a4_1.controller("c4_1",function ($scope,$q) { 
                    var defer = $q.defer();
                    $scope.action = function (type) {  
                        //开始前的协商
                        defer.notify(0);
                        type?defer.resolve(1):defer.reject(1);
                    }
                    var promise = defer.promise;
                    promise.then(function (n) {
                        n++;
                        $scope.t1 = "已经处理完成:" + n;
                      },function(n) {
                          n++;
                          $scope.t1 = "未完成原因:" + n;
                      },function (n) {  
                          n++;
                          $scope.t0 = "正在处理中:"+ n;
                      }
                      )
                 })
        </script>
      </body>
      </html>
      • 输出结果

      无论是单机哪个按钮,页面中显示“正在处理中”的值都是1,“已处理完成”或者“未完成原因”都是2。

      • 代码解析

      在执行resovle 或者 reject方法之前由于先执行了延期对象的notify()方法,并给t赋值为0,执行后,在notify的回调函数中,累加了一次t值,此时t值为1。

    • promise对象在$http中的应用

    • 介绍

      在$http中使用promise对象,并没有根本性的变化,但他会减少数据加载时的白框现象或等待加载的时间。

    • 代码介绍

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>$http</title>
        <script src="components/angular/angular.min.js"></script>
      </head>
      <body ng-app="a4_3">
        <div ng-controller="c4_3">
            <!-- <input id="btnAlert" type="button" value="alert the infor" ng-click="onClick('alert sucecss')"> -->
        </div>
        <script>
            var a4_3 = angular.module('a4_3',[])
                .factory('async',function($q,$http){
                    var defer = $q.defer();
                    $http.get()
                    .success(function(data){
                        defer.resolve(data);
                    })
                    .error(function(reason){
                        defer.reject(reason);
                    })
                    return defer.promise;
                })
                .controller('c4_3',function($scope,async){
                    var promise = async;
                    promise.then(function(resp){
                        $scope.result = '请求成功';
                    },function(resp){
                        $scope.result = '请求失败';
                    })
                })
        </script>
      </body>
      </html>

猜你喜欢

转载自blog.csdn.net/buzzeq/article/details/79358979