深入理解Angularjs中的$resource服务


Posted in Javascript onDecember 31, 2016

一、$resource服务介绍

$http服务提供的实现极为简单和低级,可以用来发送XHR请求,同时它还为你提供了很大的可控性和灵活性。但是,在大多数情况下,我们需要处理对象,以及封装了特定属性和方法的对象模型,例如一个person对象(带有详细信息),或者一个信用卡对象。

$resource就是为这一功能而设计的。AngularJS中的resource(资源)允许我们用描述性的方式来定义对象模型,它可以描述以下内容:

  1. 资源在服务端的URL。
  2. 常用的请求参数类型。
  3. 一些附加的方法(你可以自动获得get、save、query、remove和delete方法),这些方法为对象模型包装了特定的功能和业务逻辑(例如信用卡对象的charge()方法)。
  4. 期望获得的响应类型(一个数组或者一个对象)。
  5. 协议头。

使用Angular所提供的$resource对象,你可以根据各种需求查询服务器;除此之外,你还可以把服务端返回的对象当成已经持久好的数据模型,你可以修改它们,并且可以把它们持久化。

ngResource是一个独立的、可选的模块,因此,并没有默认包含在Angular中, 为了使用它,需要:

1、在加载的脚本文件中包含angular-resource.js.

例如: <script src="http://cdn.bootcss.com/angular-resource/1.5.8/angular-resource.min.js"></script>

2、在模块依赖声明中包含ngResource

例如: angular.module(‘myapp', [‘ngResource'])

3、在需要的地方使用注入的$resource服务。

格式: var obj=$resource(url,[,paramsDefaults],[,actions])

obj表示请求服务器指定url地址后返回的`$resource`对象,该对象中就包含了**与服务端进行数据交互的全部API**。

参数url表示请求服务器的地址,其中允许占位符变量,该变量必须以`:`为前缀

例如:

`var obj=$resource('url?action=:act');`
 `obj.$save{act:'save'}`

那么,在执行save动作时,向服务端发送的实际地址就为`url?action=save`。

此外,可选参数`paramsDefaults`是一个对象,用于设置请求时的默认参数值,在发送请求时,该对象中的全部值将自动进行序列化,如遇占位符变量自动替换,并将结果添加到url请求之后

代码如下:

var obj=`$resource`('url?action=:act',{
 act:'save',
 a:'1',
 b:'2'
 });

执行上述代码后,向服务器发送的实际地址是`url?action=save&a=1&b=2`。

另外一个可选参数`actions`的功能是扩展默认资源动作,例如,可以在该对象中自定义新的方法:

var boj=$resource('url?action=:act',{
 ...
 },{
 a:{
 method:'get'
 }
 });

然后就可以在$resource对象中直接调用在可选参数actions中自定义的方法a,即obj.$a()

二、 $resource服务所返回?愣韵笾兴????个与服务端交互常用API

1、$resource服务返回对象中的GET类型请求

包含两个api,分别为get  query,调用格式如下:

var obj=$resource('url');
 //get()方法
 obj.get(params,successFn,errorFn);
 //query方法
 obj.query(params,successFn,errorFn);

这两个api的请求参数相同,区别在于,**get返回值可以是单个资源,但是query必须返回一个数组或集合类的资源。**

2、$resource服务返回对象中的非GET类型请求

包含3个api,分别为save  delete  remove,调用格式如下:

var obj=$resource('url');
 //save()方法
 obj.save(params,postData,successFn,errorFn);
 //delete方法
 obj.save(params,postData,successFn,errorFn);
 //remove方法
 obj.save(params,postData,successFn,errorFn);

其中,delete方法和remove方法作用享用,区别在于remove可以解决IE浏览器中delete是Javascript保留字而导致的错误问题。

<div ng-controller='myController'>
 <ul>
 <li ng-repeat='item in items'>
 <span>{{item.Code}}</span>
 <span>{{item.Name}}</span>
 <span>{{item.Gender}}</span>
 </li>
 </ul>
 <div>
 Key: <input type="text" ng-model='key' />
 <button ng-click='save()'>保存</button>
 <div>{{result}}</div>
 </div>
 </div>
 <script type="text/javascript">
 angular.module('myapp',['ngResource'])
 .config(function($httpProvider){
 $httpProvider.defaults.transformRequest=function(obj){
 var arrStr=[];
 for(var p in obj){
  arrStr.push(encodeURIComponent(p)+"="+encodeURIComponent(obj[p]));
 }
 return arrStr.join("&");
 };
 $httpProvider.defaults.headers.post={
  'Content-Type':'application/x-www-form-urlencoded'
 }
 })
 .controller('myController',['$scope','$resource',function($scope,$resource){
 var stus=$resource('/info');
 ///info?action=search
 stus.query({action:'search'},function(resp){
  $scope.items=resp;
 });
 $scope.save=function(){
  var data={
  key:$scope.key
  };
  stus.save({action:'save'},data,function(resp){
  $scope.result=(resp[0]=='1')?'保存成功':"保存失败";
  });
 }
 }])
 </script>

对应的服务器端文件,使用了Express架构,核心代码如下:

//对于query请求
 app.get('/info',function(req,res){
 var info=[
 {Code:'1001',Name:'zhangsan',Gender:'female'},
 {Code:'1002',Name:'lisi',Gender:'male'}
 ];
 res.status(200).json(info);
 });
 //对于save请求
 app.post('/info',function(req,res){
 if(req.body.key=='1001'){
 res.send('1');
 }else{
 res.send('0')
 }
 });

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

var obj=$resource(url,[,paramsDefaults],[,actions])

在第三个可选参数中,通过key/value的方式自定义。

<div ng-controller='myController'>
 <div>
 <div>{{r0}}</div>
 <div>{{r1}}</div>
 <div>{{r2}}</div>
 <button ng-click='click()'>开始</button>
 </div>
 </div>
 <script type="text/javascript">
 var url='/self?action=:act';
 angular.module('myapp',['ngResource'])
 .config(function($httpProvider){
 $httpProvider.defaults.transformRequest=function(obj){
 var arrStr=[];
 for(var p in obj){
  arrStr.push(encodeURIComponent(p)+"="+encodeURIComponent(obj[p]));
 }
 return arrStr.join("&");
 };
 $httpProvider.defaults.headers.post={
  'Content-Type':'application/x-www-form-urlencoded'
 }
 })
 .factory('custom',['$resource',function($resource){
 return $resource(url,{act:'search'},
  {
   update:{
   method:'POST',//使用POST方式请求服务器
   params:{
   update:true
   },
   isArray:false //表示调用该方法后,服务器返回的数据可以不是一个数组
   }
  });
 }])
 .controller('myController',['$scope','custom',function($scope,custom){
 $scope.click=function(){
  //这里的id是放在url后面的,/self?action=search&id=1001
  custom.get({id:'1001'},function(resp0){
  $scope.r0=(resp0[0]=='1')?'查找成功':'查找失败';
  resp0.key='1001';
  // /self?action=update&update=true
  resp0.$update({act:'update'},function(resp1){
  $scope.r1=(resp0[0]=='1')?'更新成功':'更新失败';
  //这里的key是放在数据body体里面的
  resp1.key='1002';
  //self?action=save
  resp1.$save({act:'save'},function(resp2){
  $scope.r2=(resp0[0]=='1')?'保存成功':'保存失败';
  })
  })
  })
 }
 }])
 </script>

对应的服务器端文件,使用了Express架构,核心代码如下:

// /self?action=search&id=1001
 app.get('/self',function(req,res){
 if(req.query.action=='search'){
 console.log('req.params.id:'+req.params.id);
 if(req.query.id=='1001'){
 res.send('1');
 }else{
 res.send('0');
 }
 }
 });

 // /self?action=update&update=true /self?action=save
 app.post('/self',function(req,res){
 if(req.query.action=='update'){
 if(req.body.key=='1001' && req.query.update=='true'){
 res.send('1');
 }else{
 res.send('0');
 }
 }else if(req.query.action=='save'){
 if(req.body.key=='1002'){
 res.send('1');
 }else{
 res.send('0');
 }
 }
 })

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
页面中js执行顺序
Nov 09 Javascript
自制基于jQuery的智能提示插件一枚
Feb 18 Javascript
dojo随手记 gird组件引用
Feb 24 Javascript
Jquery动态替换div内容及动态展示的方法
Jan 23 Javascript
Jsonp post 跨域方案
Jul 06 Javascript
js轮盘抽奖实例分析
Apr 17 Javascript
从零开始学习Node.js系列教程之设置HTTP头的方法示例
Apr 13 Javascript
javascript 中iframe高度自适应(同域)实例详解
May 16 Javascript
React中嵌套组件与被嵌套组件的通信过程
Jul 11 Javascript
jQuery使用each遍历循环的方法
Sep 19 jQuery
记一次用vue做的活动页的方法步骤
Apr 11 Javascript
js实现简单的日历显示效果函数示例
Nov 25 Javascript
BootStrap Fileinput的使用教程
Dec 30 #Javascript
BootStrap Fileinput初始化时的一些参数
Dec 30 #Javascript
bootstrapValidator表单验证插件学习
Dec 30 #Javascript
JS实现类似百叶窗下拉菜单效果
Dec 30 #Javascript
BootStrap实现轮播图效果(收藏)
Dec 30 #Javascript
jQuery Ajax 实现在html页面实时显示用户登录状态
Dec 30 #Javascript
javascript实现简单的可随机变色网页计算器示例
Dec 30 #Javascript
You might like
PHP字符串 ==比较运算符的副作用
2009/10/21 PHP
php在服务器执行exec命令失败的解决方法
2012/03/03 PHP
php获取本地图片文件并生成xml文件输出具体思路
2013/04/27 PHP
php判断用户是否手机访问代码
2015/06/08 PHP
php 开发中加密的几种方法总结
2017/03/22 PHP
PHP检查文件是否存在,不存在自动创建及读取文件内容操作示例
2020/01/23 PHP
php操作redis常见方法示例【key与value操作】
2020/04/14 PHP
javascript Firefox与IE 替换节点的方法
2010/02/24 Javascript
ext 列表页面关于多行查询的办法
2010/03/25 Javascript
js 数组的for循环到底应该怎么写?
2010/05/31 Javascript
JavaScript 联动的无限级封装类,数据采用非Ajax方式,随意添加联动
2010/06/29 Javascript
自己编写的类似JS的trim方法
2013/10/09 Javascript
使用jQuery快速解决input中placeholder值在ie中无法支持的问题
2014/01/02 Javascript
比例尺、缩略图、平移缩放之百度地图添加控件方法
2015/08/03 Javascript
JavaScript实现动态删除列表框值的方法
2015/08/12 Javascript
js和jquery分别验证单选框、复选框、下拉框
2015/12/17 Javascript
BootStrap Fileinput的使用教程
2016/12/30 Javascript
Angular.js之作用域scope'@','=','&amp;'实例详解
2017/02/28 Javascript
Vue.Draggable实现拖拽效果
2020/07/29 Javascript
javaScript封装的各种写法
2017/08/14 Javascript
js禁止浏览器页面后退功能的实例(推荐)
2017/09/01 Javascript
react实现换肤功能的示例代码
2018/08/14 Javascript
javascript中join方法实例讲解
2019/02/21 Javascript
vue-cli中使用高德地图的方法示例
2019/03/28 Javascript
vue项目前端知识点整理【收藏】
2019/05/13 Javascript
[03:42]2016国际邀请赛中国区预选赛首日现场玩家采访
2016/06/26 DOTA
python如何实现excel数据添加到mongodb
2015/07/30 Python
Python cookbook(字符串与文本)在字符串的开头或结尾处进行文本匹配操作
2018/04/20 Python
django基于restframework的CBV封装详解
2019/08/08 Python
Python爬虫:将headers请求头字符串转为字典的方法
2019/08/21 Python
Python实现敏感词过滤的4种方法
2020/09/12 Python
装饰工程师岗位职责
2014/06/08 职场文书
化学专业毕业生求职信
2014/07/28 职场文书
Python数据可视化之基于pyecharts实现的地理图表的绘制
2021/06/10 Python
关于maven依赖 ${xxx.version}报错问题
2022/01/18 Java/Android
Win11无法访问设备和打印机 如何解决页面空白
2022/04/09 数码科技