在angular中有一个特别为RESTful架构而定制的服务,是在$http的基础上进行了封装.

但是为了学习,我们先看看用直接$http是如何构建RESTful架构的:

假设有一个银行卡的列表.需要的功能有:

可以通过id来获取用户123的指定id的卡     'GET'  'card/user/123/id'

可以获取用户123的所有的银行卡             'GET'  'card/user/123'

可以更新用户123的指定id的卡                'POST' 'card/user/123/id'

可以为用户123新增一张银行卡                'POST'  'card/user/123'

可以删除用户123的指定id的卡                 'DELETE'  'card/user/123/id'

html:

<!DOCTYPE html>
<html ng-app = 'HttpREST'>
<head>
<title>18.5 $http(RESTful)</title>
<meta charset="utf-8">
<script src="angular.js"></script>
<script src="script.js"></script>
<style type="text/css">
*{
font-family:'MICROSOFT YAHEI';
font-size:12px
}
</style>
</head>
<body>
<div ng-controller = "Card">
<button ng-click="updataCard()">更新id为3的银行卡</button>
<br/>
<button ng-click="addCard()">添加一张新的银行卡</button>
<br/>
<button ng-click="delCard()">删除id为3的银行卡</button>
<br/>
<span>{{card_1}}</span>
<br/>
<span>{{card_2}}</span>
<br/>
<span>{{card_3}}</span>
<br/>
<span>{{card_4}}</span>
<br/>
<span>{{cards}}</span>
</div> </body>
</html>

js:

var HttpREST = angular.module('HttpREST',[]);

HttpREST.factory('httpCard',function($http,$q){
var baseUrl = '/card/user/123';
return {
//获取用户123的指定id的卡
getById:function(id){
var defer = $q.defer();
$http({
method:'get',
url:baseUrl+'/'+id
}).success(function(data){
defer.resolve(data);
}).error(function(data){
defer.reject(data);
});
return defer.promise
},
//获取用户123的所有卡
query:function(){
var defer = $q.defer();
$http({
method:'get',
url:baseUrl
}).success(function(data){
defer.resolve(data);
}).error(function(data){
defer.reject(data);
});
return defer.promise
},
//保存一张卡,如果原来就有id,那就是更新这张卡,如果原来没有这张卡,那就是新建这张卡,
//新建路径就是baseUrl,更新路径就是baseUrl+id
save:function(card){
var defer = $q.defer();
var url = card.id ? baseUrl+'/'+card.id : baseUrl;
$http({
method:'post',
url:url,
data:card
}).success(function(data){
defer.resolve(data);
}).error(function(data){
defer.reject(data);
});
return defer.promise
},
//删除用户123的指定id的卡
del:function(id){
var defer = $q.defer();
$http({
method:'delete',
url:baseUrl+'/'+id
}).success(function(data){
defer.resolve(data)
}).error(function(data){
defer.reject(data)
});
return defer.promise
}
}
}); HttpREST.controller('Card',function($scope,httpCard){
//通过id获取银行卡
$scope.card_1 = httpCard.getById(1);
$scope.card_2 = httpCard.getById(2);
$scope.card_3 = httpCard.getById(3);
//获取所有的银行卡
$scope.cards = httpCard.query();
//更新id为3的银行卡
$scope.updataCard = function(){httpCard.save({id:3,name:"工商银行"}).then(function(data){$scope.card_3 = data['name']})};
//添加id为4的银行卡
$scope.addCard = function(){httpCard.save({name:"浦发银行"}).then(function(data){$scope.card_4 = data['name']});};
$scope.delCard = function(){httpCard.del(3).then(function(data){$scope.card_3 = data});}
});

node:

var express = require('express');
var app = express();
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(__dirname)); var cards = [
{
id:1,
name:'建设银行'
},
{
id:2,
name:'中国银行'
},
{
id:3,
name:'上海银行'
}
]; app.get('/card/user/123/:id',function(req,res){
var data = cards[req.params.id-1];
res.send(data['name'])
});
app.get('/card/user/123',function(req,res){
var data=[];
for(var i in cards){
data.push(cards[i]['name'])
}
res.send(data)
}); app.post('/card/user/123/:id',function(req,res){
var index = req.params.id-1;
cards[index] = req.body;
res.send(cards[index]);
});
app.post('/card/user/123',function(req,res){
var index = cards.length;
cards[index] = req.body;
cards[index].id = index;
res.send(cards[index]);
});
app.delete('/card/user/123/:id',function(req,res){
var index = req.params.id-1;
cards[index] = null;
console.log(cards);
res.send(cards[index])
}); app.listen(3000);

1. 这里视图中的card_1,card_2,carde_3,card_4需要显示的是银行卡的name属性,所以在后台中直接返回卡的name值,而不是返回一整张卡再取name属性

2. 创建一个名为httpCard的服务,这个服务返回的对象有四个方法:

①getById: 通过id获取指定的卡的名字,显示在视图中就是card_1,carde_2,card_3

        getById:function(id){
var defer = $q.defer();
$http({
method:'get',
url:baseUrl+'/'+id
}).success(function(data){
defer.resolve(data);
}).error(function(data){
defer.reject(data);
});
return defer.promise
}

$scope.card_1 = httpCard.getById(1);
          $scope.card_2 = httpCard.getById(2);
          $scope.card_3 = httpCard.getById(3);


注意,必须使用$q,这样可以确保在获取到后台的数据后渲染视图.但是注意,$scope.card_1其实是一个promise对象,它不是真正返回到的data,真正的data是promise对象的$$v,这个在下一篇讲ngResource时会详细介绍,这里只要了解到,通过promise,视图可以获取到返回的值.

②query: 获取全部的卡的名字的数组.显示在视图中就是cards

        query:function(){
var defer = $q.defer();
$http({
method:'get',
url:baseUrl
}).success(function(data){
defer.resolve(data);
}).error(function(data){
defer.reject(data);
});
return defer.promise
} $scope.cards = httpCard.query();

③save: 保存指定id的卡(修改),或者保存一张新建的卡(新建). 显示在视图中就是card_3 和 card_4

        save:function(card){
var defer = $q.defer();
var url = card.id ? baseUrl+'/'+card.id : baseUrl;
$http({
method:'post',
url:url,
data:card
}).success(function(data){
defer.resolve(data);
}).error(function(data){
defer.reject(data);
});
return defer.promise
} //更新id为3的银行卡
$scope.updataCard = function(){httpCard.save({id:3,name:"工商银行"}).then(function(data){$scope.card_3 = data['name']})};
//添加id为4的银行卡
$scope.addCard = function(){httpCard.save({name:"浦发银行"}).then(function(data){$scope.card_4 = data['name']});};

save方法都是POST类型的请求,传入的参数就是请求体,根据请求体是否有id来判断是更新卡还是新建卡.在后台进行不同的处理.返回的值都是保存的卡.

注意,save方法返回的也是一个promise,它的then方法里的函数会在请求完成(也就是defer.resolve或者defer.reject,也就是得到了响应体)以后才被执行,参数就是请求返回的值,在这里也就被保存的卡(无论是更新还是新建),

然后$scope.card_3 = data['name'],这个时候,card_3不再是promise对象了,而真的是一个数据了.在ngResource中,处理方法会和此处有所不同.会在下一篇中详解.

④del: 删除指定id的卡.显示在视图中就是card_3

        del:function(id){
var defer = $q.defer();
$http({
method:'delete',
url:baseUrl+'/'+id
}).success(function(data){
defer.resolve(data)
}).error(function(data){
defer.reject(data)
});
return defer.promise
} //删除id为3的银行卡
$scope.delCard = function(){httpCard.del(3).then(function(data){$scope.card_3 = data});}

删除和保存性质是一样的,都是返回一个promise对象,响应成功后得到响应体作为参数被传入then的函数中,然后被执行.由于是删除,所以返回null,card_3就变成了null,视图中的card_3也就不见了

顺便提一下,node里需要使用express.methodOverride(),这样就可以为app创建处理deletel方式的请求了.

app.use(express.methodOverride());
app.delete('/card/user/123/:id',function(req,res){
var index = req.params.id-1;
cards[index] = null;
console.log(cards);
res.send(cards[index])
});

运行node后,看到的页面如下:

1.获取到了card_1,card_2,card_3,cards

2.点击更新id为3的银行卡,card_3变为'工商银行'

3.点击添加一张新的银行卡,card_4显示为'浦发银行'

4.点击删除id为3的银行卡,card_3就被清除了

完整代码地址: https://github.com/OOP-Code-Bunny/angular/tree/master/OREILLY/18.5%20%24http(RESTful)

angular学习笔记(二十七)-$http(5)-使用$http构建RESTful架构的更多相关文章

  1. angular学习笔记(二十八)-$http(6)-使用ngResource模块构建RESTful架构

    ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入 ...

  2. angular学习笔记(二十八-附2)-$http,$resource中的promise对象

    下面这种promise的用法,我从第一篇$http笔记到$resource笔记中,一直都有用到: HttpREST.factory('cardResource',function($resource) ...

  3. angular学习笔记(二十九)-$q服务

    angular中的$q是用来处理异步的(主要当然是http交互啦~). $q采用的是promise式的异步编程.什么是promise异步编程呢? 异步编程最重要的核心就是回调,因为有回调函数,所以才构 ...

  4. angular学习笔记(二)-创建angular模块

    如果在页面的html标签(或任意标签)中添加ng-app,表示对整个页面应用angular来管理. 他是一个模块. 模块有助于把东西从全局命名空间中隔离. 今天学习如何自定义创建模块: <!DO ...

  5. angular学习笔记(二十八-附1)-$resource中的资源的方法

    通过$resource获取到的资源,或者是通过$resource实例化的资源,资源本身就拥有了一些方法,$save,$delete,$remove,可以直接调用来保存该资源: 比如有一个$resour ...

  6. angular学习笔记(二十六)-$http(4)-设置请求超时

    本篇主要讲解$http(config)的config中的timeout项: $http({ timeout: number }) 数值,从发出请求开始计算,等待的毫秒数,超过这个数还没有响应,则返回错 ...

  7. angular学习笔记(二十五)-$http(3)-转换请求和响应格式

    本篇主要讲解$http(config)的config中的tranformRequest项和transformResponse项 1. transformRequest: $http({ transfo ...

  8. angular学习笔记(二十四)-$http(2)-设置http请求头

    1. angular默认的请求头: 其中,Accept 和 X-Requested-With是$http自带的默认配置 Accept:application/json,text/plain       ...

  9. angular学习笔记(二十三)-$http(1)-api

    之前说到的$http.get和$http.post,都是基于$http的快捷方式.下面来说说完整的$http: $http(config) $http接受一个json格式的参数config: conf ...

随机推荐

  1. 谈一谈chrome浏览器使用

    F3或Ctrl+F5: 查找本网页里面的内容,匹配到即可高亮. F6:回到地址栏 Ctrl+J:显示下载内容 Ctrl+N: 新建一个标签页 F10:选项 F11:显示全屏 F12:调试网页 大家有什 ...

  2. 关于ARM立即数的理解

    转自:http://blog.sina.com.cn/s/blog_9bad4f090101e14d.html 一.立即数指令码的组成 ARM公司将32bit指令码分为如下两部分: 32bit立即数通 ...

  3. MVC Linq动态排序

    在nuget 中searh System.Linq.Dynamic 安装对应的版本, 这样都可以使用了 var orderExpression = string.Format("{0} {1 ...

  4. 警察与小偷的实现之中的一个client与服务端通信

    来源于ISCC 2012 破解关第四题 目的是通过逆向police.实现一个thief,可以与police进行通信 实际上就是一个RSA加密通信的样例,我们通过自己编写client和服务端来实现上面的 ...

  5. 查看tomcat启动文件都干点啥---catalina.bat(转)

    在上一次查看tomcat启动文件都干点啥一文中,我们总结出,startup.bat文件的作用就是找到catalina.bat文件,然后把参数传递给它,在startup.bat中,调用catalina. ...

  6. Linux下MySQL链接被防火墙阻止

    Linux下安装了MySQL,不能从其它机器访问 帐号已经授权从任意主机进行访问 vi /etc/sysconfig/iptables 在后面添加 -A RH-Firewall-1-INPUT -m ...

  7. Android API之android.widget.Filterable

      android.widget.Filterable 定义了一种可过滤的行为.Filterable接口通常有android.widget.Adapter来实现.接口Filterable中有个抽象方法 ...

  8. PHP-二进制文件和文本文件的区别

    一.文本文件和二进制文件的定义 计算机上所有文件存储在存储设备上都是二进制的, 所以文本文件和二进制文件的区别并不是物理上的, 而是逻辑上的!简单来说, 文本文件是基于字符编码的文件, 常见的编码有A ...

  9. HUDOJ-----1394Minimum Inversion Number

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  10. 二叉搜索树 C语言实现

    1.二叉搜索树基本概念 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是一棵具有如下特性的非空二叉树: (1)若它的左子树非空,则左子树上所有结点的关键字均小于根结点的关键字: (2)若它的右子树非 ...