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>