转自:https://www.cnblogs.com/best/tag/Angular/
服务从代码直接与服务器进行交互,底层是通过实现,与中http服务从AngularJS代码直接与Web服务器进行交互,底层是通过AJAX实现,与jQuery中.ajax类似
通过$http封装后的方法:
delete(url,[config]) 发送谓词为delete的异步请求
get(url,[config]) 发送谓词为get的异步请求
head(url,[config]) 发送谓词为head的异步请求
jsonp(url,[config]) 发送通过jsonp实现跨域的同步请求的请求
post(url,data,[config]) 发送谓词为post的异步请求
put(url,data[config]) 发送谓词为put的异步请求
基本用法:
$http({method: 'GET', url: '/someUrl'}).
success(function(data, status, headers, config) {
}).
error(function(data, status, headers, config) {
});
详细的配置如下:
这里使用NodeJS+Express作为后台服务,完成一个简单的汽车管理功能:
cars.js
var express = require('express'); var router = express.Router(); var _= require('lodash'); var cars=[]; cars.push({id:201701,name:"BMW",price:190,speed:"210km/h",color:"白色"}); cars.push({id:201702,name:"BYD",price:25,speed:"160km/h",color:"红色"}); cars.push({id:201703,name:"Benz",price:300,speed:"215km/h",color:"蓝色"}); cars.push({id:201704,name:"Honda",price:190,speed:"170km/h",color:"黑色"}); cars.push({id:201705,name:"QQ",price:130,speed:"210km/h",color:"白色"}); /* Get */ /*获得所有汽车*/ /*url /cars/*/ router.get('/', function(req, res, next) { res.json(cars); }); /*Get*/ /*获得汽车通过id*/ /*url:/cars/:id */ router.get('/:id', function(req, res, next) { //从路径中映射参数,转换成数字 var id=parseInt(req.params.id); var car=_.find(cars,{id:id}); res.json(car); }); /*Post*/ /*添加汽车*/ /*url:/cars/car */ router.post('/car', function(req, res, next) { console.log("收到请求"); var car=req.body; //从请求正文中获得json对象 car.id=_.last(cars).id+1; //将编号修改为最后一辆车的编号+1 cars.push(car); //将汽车对象添加到集合中 res.json(car); //将添加成功的车以json的形式返回 }); /*Put*/ /*修改汽车*/ /*url:/cars/car */ router.put('/car', function(req, res, next) { var car=req.body; //从请求正文中获得json对象 console.log(req.body); var index=_.findIndex(cars,{id:parseInt(car.id)}); //根据id获得车在集合中的下标 cars[index]=car; //替换原对象 //res.json(car); //将修改后的车以json的形式返回 res.send({status:"success", message:"更新成功!"}); }); /*Delete*/ /*删除汽车*/ /*url:/cars/:id */ router.delete('/id/:id', function(req, res, next) { //获得url中的编号参数 var id=parseInt(req.params.id); var index=_.findIndex(cars,{id:id}); //根据id获得车在集合中的下标 cars.splice(index,1); //在cars数组中删除下标从index开始的1条数据 res.json(cars); }); module.exports = router;
app.js
var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var index = require('./routes/index'); var users = require('./routes/users'); var pdts = require('./routes/product'); var task = require('./routes/task'); var cars = require('./routes/cars'); var app = express(); //指定视图引擎为ejs app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "content-type"); res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By",' 3.2.1') res.header("Content-Type", "application/json;charset=utf-8"); next(); }); app.use('/', index); app.use('/users', users); app.use('/pdt', pdts); app.use("/task",task); app.use("/cars",cars); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
www
#!/usr/bin/env node /** * 依赖模块,导入 */ var app = require('../app'); var debug = require('debug')('nodejsexpress:server'); var http = require('http'); /** * 从上下文环境中获得监听端口,如果空则3000 */ var port = normalizePort(process.env.PORT || '3000'); app.set('port', port); /** * 创建Web服务器 */ var server = http.createServer(app); /** * 开始监听 */ server.listen(port); server.on('error', onError); //指定发生错误时的事件 server.on('listening', onListening); //当监听成功时的回调 /** * 规范化端口 */ function normalizePort(val) { var port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } /** *错误事件监听 */ function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; //错误处理 switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); //结束程序 break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * 当用户访问服务器成功时的回调 */ function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); }
示例代码:
<!DOCTYPE html> <!--指定angular管理的范围--> <html ng-app="carApp"> <head> <meta charset="UTF-8"> <title>服务</title> <style> * { margin: 0; padding: 0; font-family: microsoft yahei; font-size: 14px; } body { padding-top: 20px; } .main { 90%; margin: 0 auto; border: 1px solid #777; padding: 20px; } .main .title { font-size: 20px; font-weight: normal; border-bottom: 1px solid #ccc; margin-bottom: 15px; padding-bottom: 5px; color: blue; } .main .title span { display: inline-block; font-size: 20px; background: blue; color: #fff; padding: 0 8px; background: blue; } a { color: blue; text-decoration: none; } a:hover { color: orangered; } .tab td, .tab, .tab th { border: 1px solid #777; border-collapse: collapse; } .tab td, .tab th { line-height: 26px; height: 26px; padding-left: 5px; } .abtn { display: inline-block; height: 20px; line-height: 20px; background: blue; color: #fff; padding: 0 5px; } .btn { height: 20px; line-height: 20px; background: blue; color: #fff; padding: 0 8px; border: 0; } .abtn:hover, .btn:hover { background: orangered; color: #fff; } p { padding: 5px 0; } fieldset { margin-top: 10px; border: 1px solid #ccc; padding: 5px 10px; } fieldset legend { margin-left: 10px; font-size: 16px; } </style> </head> <body> <!--指定控制器的作用范围--> <form ng-controller="CarController" class="main"> <h2 class="title"><span>汽车管理</span></h2> <table border="1" width="100%" class="tab"> <tr> <th>序列</th> <th>编号</th> <th>名称</th> <th>价格</th> <th>颜色</th> <th>速度</th> <th>操作</th> </tr> <tr ng-repeat="c in cars"> <td>{{$index+1}}</td> <td>{{c.id}}</td> <td>{{c.name}}</td> <td>{{c.price}}</td> <td>{{c.color}}</td> <td>{{c.speed}}</td> <td> <a href="#" ng-click="del(c.id)">删除</a> <a href="#" ng-click="edit(c)">编辑</a> </td> </tr> </table> <fieldset> <legend>汽车详细</legend> <p> <label for="id">编号</label> <input ng-model="car.id" id="id" ng-readonly="true" /> </p> <p> <label for="name">名称</label> <input ng-model="car.name" id="name" /> </p> <p> <label for="price">价格</label> <input ng-model="car.price" id="price" /> </p> <p> <label for="color">颜色</label> <input ng-model="car.color" id="color" /> </p> <p> <label for="color">速度</label> <input ng-model="car.speed" id="speed" /> </p> <button ng-click="save()" class="btn">保存</button> <button ng-click="clear()" class="btn">清空</button> </fieldset> </form> <!--引入angularjs框架--> <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定义模块,指定依赖项为空 var carApp = angular.module("carApp", []); //定义控制器,指定控制器的名称,$scope是全局对象 carApp.controller("CarController", ['$scope', '$http', function($scope, $http) { $scope.cars = []; $scope.save = function() { $http({ url:"http://127.0.0.1:3000/cars/car", data:$scope.car, method: $scope.car.id?"PUT":"POST" }) .success(function(data, status, headers, config) { if($scope.car.id){ alert("修改成功"); }else{ $scope.cars.push(data); } }) .error(function(data, status, headers, config) { alert(status); }); } $scope.edit=function(c){ $scope.car=c; } $scope.clear=function(){ $scope.car={}; } $http.get("http://127.0.0.1:3000/cars") .success(function(data, status, headers, config) { $scope.cars = data; }) .error(function(data, status, headers, config) { alert(status); }); $scope.del = function(id) { $http.delete("http://127.0.0.1:3000/cars/id/" + id) .success(function(data, status, headers, config) { $scope.cars = data; }) .error(function(data, status, headers, config) { alert(status); }); } }]); </script> </body> </html>
运行结果:
问题:如果后台服务不是Restful,不接收application/json的参数,则需要修改。Angular的post和put请求Content-Type: application/json默认情况下,jQuery传输数据使用Content-Type: x-www-form-urlencodedand和类似于"foo=bar&baz=moe"的序列,然而AngularJS,传输数据使用Content-Type: application/json和{ "foo": "bar", "baz": "moe" }这样的json序列。请求时修改请求头部内容:
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }
$httpParamSerializerJQLike 序列化参数,这个服务需要单独依赖。
示例:
结果: