深入理解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 相关文章推荐
Add a Picture to a Microsoft Word Document
Jun 15 Javascript
js下通过prototype扩展实现indexOf的代码
Dec 08 Javascript
jQuery结合CSS制作漂亮的select下拉菜单
May 03 Javascript
ES6中的数组扩展方法
Aug 26 Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
Sep 05 Javascript
纯JavaScript手写图片轮播代码
Oct 20 Javascript
jQuery联动日历的实例解析
Dec 02 Javascript
Bootstrap 表单验证formValidation 实现表单动态验证功能
May 17 Javascript
Node.js使用Express.Router的方法
Nov 14 Javascript
angular2 ng2-file-upload上传示例代码
Aug 23 Javascript
vue自定义指令的创建和使用方法实例分析
Dec 04 Javascript
详解vue挂载到dom上会发生什么
Jan 20 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文章按日期(月日)SQL归档语句
2012/11/29 PHP
PHP解密Unicode及Escape加密字符串
2015/05/17 PHP
PHP实现的策略模式简单示例
2017/08/25 PHP
PHP使用Redis实现Session共享的实现示例
2019/05/12 PHP
javascript 打印内容方法小结
2009/11/04 Javascript
使用jquery与图片美化checkbox和radio控件的代码(打包下载)
2010/11/11 Javascript
获取css样式表内样式的js函数currentStyle(IE),defaultView(FF)
2011/02/14 Javascript
动态改变div的z-index属性的简单实例
2013/08/08 Javascript
JavaScript简单实现鼠标拖动选择功能
2014/03/06 Javascript
基于jquery实现可定制的web在线富文本编辑器附源码下载
2015/11/17 Javascript
基于jquery fly插件实现加入购物车抛物线动画效果
2016/04/05 Javascript
你不需要jQuery(三) 新AJAX方法fetch()
2016/06/14 Javascript
JS 日期与时间戮相互转化的简单实例
2016/06/22 Javascript
AngularJS ng-repeat数组有重复值的解决方法
2016/10/23 Javascript
12 款 JS 代码测试必备工具(翻译)
2016/12/13 Javascript
详解用webpack把我们的业务模块分开打包的方法
2017/07/20 Javascript
在小程序/mpvue中使用flyio发起网络请求的方法
2018/09/13 Javascript
深入了解JavaScript 私有化
2019/05/30 Javascript
layui 实现加载动画以及非真实加载进度的方法
2019/09/23 Javascript
一起写一个即插即用的Vue Loading插件实现
2019/10/31 Javascript
VUE 组件转换为微信小程序组件的方法
2019/11/06 Javascript
[00:59]PWL开团时刻DAY7——我在赶
2020/11/06 DOTA
Python2.5/2.6实用教程 入门基础篇
2009/11/29 Python
用Python和MD5实现网站挂马检测程序
2014/03/13 Python
Python中的面向对象编程详解(下)
2015/04/13 Python
Python爬虫实现全国失信被执行人名单查询功能示例
2018/05/03 Python
matplotlib subplots 调整子图间矩的实例
2018/05/25 Python
python寻找list中最大值、最小值并返回其所在位置的方法
2018/06/27 Python
python监测当前联网状态并连接的实例
2018/12/18 Python
Python动态参数/命名空间/函数嵌套/global和nonlocal
2019/05/29 Python
在Django中实现添加user到group并查看
2019/11/18 Python
python 非线性规划方式(scipy.optimize.minimize)
2020/02/11 Python
Coccinelle官网:意大利的著名皮具品牌
2019/05/15 全球购物
公司董事长职责
2013/12/12 职场文书
2015年绩效考核工作总结
2015/05/23 职场文书
日本官方排名前10的动漫,名侦探柯南上榜,第一是一部创造历史的动漫
2022/03/18 日漫