angular学习笔记(二十七)-$http(5)-使用$http构建RESTful架构
在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架构的更多相关文章
- angular学习笔记(二十八)-$http(6)-使用ngResource模块构建RESTful架构
		ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入 ... 
- angular学习笔记(二十八-附2)-$http,$resource中的promise对象
		下面这种promise的用法,我从第一篇$http笔记到$resource笔记中,一直都有用到: HttpREST.factory('cardResource',function($resource) ... 
- angular学习笔记(二十九)-$q服务
		angular中的$q是用来处理异步的(主要当然是http交互啦~). $q采用的是promise式的异步编程.什么是promise异步编程呢? 异步编程最重要的核心就是回调,因为有回调函数,所以才构 ... 
- angular学习笔记(二)-创建angular模块
		如果在页面的html标签(或任意标签)中添加ng-app,表示对整个页面应用angular来管理. 他是一个模块. 模块有助于把东西从全局命名空间中隔离. 今天学习如何自定义创建模块: <!DO ... 
- angular学习笔记(二十八-附1)-$resource中的资源的方法
		通过$resource获取到的资源,或者是通过$resource实例化的资源,资源本身就拥有了一些方法,$save,$delete,$remove,可以直接调用来保存该资源: 比如有一个$resour ... 
- angular学习笔记(二十六)-$http(4)-设置请求超时
		本篇主要讲解$http(config)的config中的timeout项: $http({ timeout: number }) 数值,从发出请求开始计算,等待的毫秒数,超过这个数还没有响应,则返回错 ... 
- angular学习笔记(二十五)-$http(3)-转换请求和响应格式
		本篇主要讲解$http(config)的config中的tranformRequest项和transformResponse项 1. transformRequest: $http({ transfo ... 
- angular学习笔记(二十四)-$http(2)-设置http请求头
		1. angular默认的请求头: 其中,Accept 和 X-Requested-With是$http自带的默认配置 Accept:application/json,text/plain ... 
- angular学习笔记(二十三)-$http(1)-api
		之前说到的$http.get和$http.post,都是基于$http的快捷方式.下面来说说完整的$http: $http(config) $http接受一个json格式的参数config: conf ... 
随机推荐
- ADS ARM 汇编和GNU ARM汇编
			Linux/Unix内核源代码用的编译器是GCC,而GCC采用的是AT&T的汇编格式,这与ADS下使用的汇编格式是不同的. 两种汇编格式的部分对比如下: GNU ARM汇编 ADS ARM汇编 ... 
- Linux高性能server编程——多线程编程(下)
			多线程编程 条件变量 假设说相互排斥锁是用于同步线程对共享数据的訪问的话.那么条件变量则是用于线程之间同步共享数据的值. 条件变量提供了一种线程间的通信机制:当某个共享数据达到某个值得时候,唤醒等待这 ... 
- Android自己定义控件:进度条的四种实现方式
			前三种实现方式代码出自: http://stormzhang.com/openandroid/2013/11/15/android-custom-loading/ (源代码下载)http://down ... 
- hdu 4865 Peter's Hobby(概率dp)
			http://acm.hdu.edu.cn/showproblem.php? pid=4865 大致题意:有三种天气和四种叶子状态.给出两个表,各自是每种天气下叶子呈现状态的概率和今天天气对明天天气的 ... 
- eclipse 修改maven项目的jdk版本
			eclipse 修改maven项目的jdk版本 CreationTime--2018年6月8日10点29分 Author:Marydon 1.情景展示 jdk版本太低,如何修改 2.错误方式 第一 ... 
- 像烟瘾一样的Adobe Flash,真的戒不掉吗?
			近来对Adobe Flash来说真是段难过的日子.Hacking Team公司外泄的440GB电子邮件数据已成为黑客挖掘安全漏洞的宝藏. 光是Flash就被发现了三个不同的漏洞: l CVE-201 ... 
- CentOS 6.4安装配置LAMP服务器
			CentOS 6.4安装配置LAMP服务器(Apache+PHP5+MySQL) 作者: 字体:[增加 减小] 类型:转载 这篇文章主要介绍了CentOS 6.4安装配置LAMP服务器(Apache+ ... 
- C++开发安卓、windows下搭建Android NDK开发环境
			1. NDK(Native Development Kit) 1.1 NDK简介 Android NDK是一套允许开发人员使用本地代码(如C/C++)进行Android APP功能开发的工具,通过这个 ... 
- 开源大数据技术专场(下午):Databircks、Intel、阿里、梨视频的技术实践
			摘要: 本论坛第一次聚集阿里Hadoop.Spark.Hbase.Jtorm各领域的技术专家,讲述Hadoop生态的过去现在未来及阿里在Hadoop大生态领域的实践与探索. 开源大数据技术专场下午场在 ... 
- Javakeyword之this
			this的作用: 1) this是当前对象的一个引用.便于对当前对象參数的使用. 2)能够返回对象的自己这个类的引用.同一时候还能够在一个构造函数其中调用还有一个构造函数 this演示样例: publ ... 
