- 浏览: 1056812 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1441)
- 软件思想&演讲 (9)
- 行业常识 (250)
- 时时疑问 (5)
- java/guava/python/php/ruby/R/scala/groovy (213)
- struct/spring/springmvc (37)
- mybatis/hibernate/JPA (10)
- mysql/oracle/sqlserver/db2/mongdb/redis/neo4j/GreenPlum/Teradata/hsqldb/Derby/sakila (268)
- js/jquery/jqueryUi/jqueryEaseyUI/extjs/angulrJs/react/es6/grunt/zepto/raphael (81)
- ZMQ/RabbitMQ/ActiveMQ/JMS/kafka (17)
- lucene/solr/nuth/elasticsearch/MG4J (167)
- html/css/ionic/nodejs/bootstrap (19)
- Linux/shell/centos (56)
- cvs/svn/git/sourceTree/gradle/ant/maven/mantis/docker/Kubernetes (26)
- sonatype nexus (1)
- tomcat/jetty/netty/jboss (9)
- 工具 (17)
- ETL/SPASS/MATLAB/RapidMiner/weka/kettle/DataX/Kylin (11)
- hadoop/spark/Hbase/Hive/pig/Zookeeper/HAWQ/cloudera/Impala/Oozie (190)
- ios/swift/android (9)
- 机器学习&算法&大数据 (18)
- Mesos是Apache下的开源分布式资源管理框架 (1)
- echarts/d3/highCharts/tableau (1)
- 行业技能图谱 (1)
- 大数据可视化 (2)
- tornado/ansible/twisted (2)
- Nagios/Cacti/Zabbix (0)
- eclipse/intellijIDEA/webstorm (5)
- cvs/svn/git/sourceTree/gradle/jira/bitbucket (4)
- jsp/jsf/flex/ZKoss (0)
- 测试技术 (2)
- splunk/flunm (2)
- 高并发/大数据量 (1)
- freemarker/vector/thymeleaf (1)
- docker/Kubernetes (2)
- dubbo/ESB/dubboX/wso2 (2)
最新评论
AngularJS的学习--$on、$emit和$broadcast的使用
•$emit只能向parent controller传递event与data
•$broadcast只能向child controller传递event与data
•$on用于接收event与data
CSS中!important的使用
CSS的原理:
我们知道,CSS写在不同的地方有不同的优先级, .css文件中的定义 < 元素style中的属性,但是如果使用!important,事情就会变得不一样。
首先,先看下面一段代码:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>测试Css中的!Important区别</title>
</head>
<style type="text/css">
.testClass{
color:blue !important;
}
</style>
<body>
<div class="testClass" style="color:red;">
测试Css中的Important
</div>
</body>
</html>
虽然元素的style中有testClass类的定义,但是在上面的css定义中的用!important限定的定义却是优先级最高的,无论是在ie6-10或者Firefox和Chrome表现都是一致的,都显示蓝色。
这种情况也同时可以说明ie6是可以识别!important的,只是这个是ie6的一个缺陷吧。如果写成下面的样式,ie6是识别不出来的:
.testClass{
color:blue !important;
color:red;
}
这样,在ie6下展示的时候会显示成红色。
当然,也可以通过以下方式来让ie6识别:
.testClass{
color:blue !important;
}
.testClass{
color:red;
}
通过以上方式也是可以让ie6显示成蓝色的。
以上实例说明使用!important的css定义是拥有最高的优先级的。只是在ie6下出了一点小的bug,注意书写方式一般可以轻松避开的。
一、首先回顾一下有哪些绑定策略?
\
看这个实在是有点抽象了,我们来看具体的实例分析吧!
二、简单的Demo实例
@绑定:传递一个字符串作为属性的值。比如 str : ‘@string’
控制器中代码部分示例:
myDirec.controller('MyCtrl3',['$scope',function($scope){
$scope.ctrlFlavor=鸡尾酒;
$scope.sayHello=function(name){
alert(Hello +name);
};
}]);
myDirec.directive(drink,function(){
return{
restrict:'AE',
scope:{
flavor:'@' //自动绑定,传递的是字符串
},
template:
{{flavor}} , }; });
页面中使用标签部分示例:
分析我们在drink指令中为什么能取得在父作用域中的值呢?原因就在于我们使用了@绑定策略,可以将ctrlFlavor赋值给flavor,这样在模板中就能取到该值了。
=绑定:指定获取属性的类型为父作用域的属性
myDirec.directive(drink2,function(){
return{
restrict:'AE',
scope:{
flavor:'=' //自动绑定
},
template:'<input type="text" ng-model="flavor/">'
};
});
页面:
执行的流程是这样的:
① 指令被编译的时候会扫描到template中的模型发现有一个flavor,
② 查找scope中是否定义:通过=与父作用域绑定,方式是传递父作用域中的属性ctrlFlavor;
③ flavor与父作用域中的ctrlFlavor属性绑定,找到它的值“鸡尾酒”;
④ 将model的值显示在模板中。
&绑定:传递的是父作用域中的函数
控制器部分:
myDirec.directive(greeting, function() {
return {
restrict:'AE',
scope:{
greet:'&'
},
template:'<input type="text" ng-model="userName">
'+
'<button ng-click="greet({name:userName})">问候一下</button>
'
};
});
页面部分:
从结果上看,三个输入框中的内容互不影响,因为都是新的独立作用域,能够完成从视图到模型的绑定。
三、Expander示例
首先看控制器代码:
/*Expander示例*/
myDirec.controller('SomeController',function($scope) {
$scope.title = '点击展开';
$scope.text = '这里是内部的显示的内容';
});
myDirec.directive('expander', function() {
return {
restrict : 'EA',
replace : true,
transclude : true,
scope : {
title : '=expanderTitle'
},
template : '
' + '
{{title}} ' + '
' + ' ', link : function(scope, element, attrs) { scope.showMe = false; scope.toggle = function() { scope.showMe = !scope.showMe; }; } }; });
再看页面部分:
{{text}}
执行的流程是这样的:
① 指令被编译的时候会扫描到template中的模型发现有一个{{title}},
② 查找scope中是否定义:通过=与父作用域绑定,方式是传递父作用域中的属性;
我总是在这里犯糊涂,解释下这个“方式是传递父作用域中的属性”,这个在哪里用的呢?
{{text}} 看到没,指令中的属性expander-title='title',这不就是传递父作用域中的属性吗?
③ expander-title与父作用域中的title属性绑定,找到它的值“点击展开”;
④ 将title的值显示在模板中。
注意:指令中的独立作用域中的属性title是为了给下面的模板使用 的,而title所对应的值,要依据页面中指令的使用传人具体的父作用域中的属性,完成属性的绑定操作。
总之、我们可以利用angularjs为我们提供的数据绑定策略来实现从父作用域向指令中传值,这个很有用哦!
bootstrap学习:
http://www.runoob.com/bootstrap/bootstrap-tutorial.html
http://www.ibootstrap.cn/
angular在通过异步提交数据时使用了与jQuery不一样的请求头部和数据序列化方式,导致部分后台程序无法正常解析数据。
原理分析(网上的分析):
[javascript] view plain copy print?
01.<span style="font-size:14px;">对于AJAX应用(使用XMLHttpRequests)来说,向服务器发起请求的传统方式是:获取一个XMLHttpRequest对象的引用、发起请求、读取响应、检查状态码,最后处理服务端的响应。整个过程示例如下:</span>
[javascript] view plain copy print?
01.var xmlhttp = new XMLHttpRequest();
02.
03.xmlhttp.onreadystatechange = function() {
04. if(xmlhttp.readystate == 4 && xmlhttp.status == 200) {
05. var response = xmlhttp.responseText;
06. }else if(xmlhttp.status == 400) { //或者可以是任何以4开头的状态码
07. //优雅地处理错误
08. }
09.};
10.
11.//建立连接
12.xmlhttp.open("GET", "http://myserver/api", true);
13.
14.//发起请求
15.xmlhttp.send();
对于简单、常用而且会经常重复的任务来说,这是一种很烦琐的工作。如果你想复用以上过程,你应该进行封装或者使用代码库。
AngularJS XHR API遵守一种通常被称为Promise的接口。由于XHR是异步调用的方法,所以服务端的响应会在未来某个不确定的时间点上返回(我们希望它立即能返回)。Promise接口规定了处理这种响应的方式,并且允许Promise的使用者以一种可预见的方式来使用它。
例如,我们要从服务端获取一个用户的信息,假设用来接受请求的后台接口位于/api/user路径上,此接口可以接受一个id属性作为URL参数,那么使用Angular的核心$http服务发起XHR请求的方法示例如下:
[javascript] view plain copy print?
01.$http.get('api/user', {params: {id:'5'}
02.}).success(function(data, status, headers, config) {
03. //加载成功之后做一些事
04.}).error(function(data, status, headers, config) {
05. //处理错误
06.});
如果你是jQuery使用者,你应该会发现,AngularJS和jQuery在对异步请求的处理方面非常类似。
上面例子中使用的$http.get方法是AngularJS的核心服务$http所提供的众多快捷方法之一。类似地,如果你想使用AngularJS向同一个URL发送POST请求,同时带上一些POST数据,你可以像下面这样做:
[javascript] view plain copy print?
01.var postData = {text:'long blob of text'};
02.//下面这一行会被当成参数附加到URL后面,所以post请求最终会变成/api/user?id=5
03.var config = {params: {id: '5'}};
04.$http.post('api/user', postData, config
05.).success(function(data, status, headers, config) {
06. //成功之后做一些事情
07.}).error(function(data, status, headers, config) {
08. //处理错误
09.});
对于大多数常用的请求类型,都有类似的快捷方法,这些请求类型包括:GET、HEAD、POST、DELETE、PUT、JSONP。
一.进一步配置请求
虽然标准的请求方式使用起来比较简单,但是,有时候会存在可配置性不佳的缺点。如果你想要实现下面这些事情就会遇到困难:
a.给请求加上一些授权头。
b.修改对缓存的处理方式。
c.用一些特殊的方式来变换发送出去的请求,或者变换接收到的响应。
在这些情况下,你可以给请求传递一个可选的配置对象,从而对请求进行深度配置。在前面的例子中,我们使用config对象指定了一个可选的URL参数。但是那里的GET和POST方法是一些快捷方式。这种深度简化之后的方法调用示例如下:
$http(config)
下面是一个基本的伪代码模板,用来调用前面的这个方法:
[javascript] view plain copy print?
01.$http({
02. method: string,
03. url: string,
04. params: object,
05. data: string or object,
06. headers: object,
07. transformRequest: function transform(data, headersGetter) or an array of functions,
08. transformResponse: function transform(data, headersGetter) or an array of functions,
09. cache: boolean or Cache object,
10. timeout: number,
11. withCredentials: boolean
12.});
GET、POST及其他快捷方法都会自动设置method参数,所以不需要手动设置。config对象会作为最后一个参数传递给$http.get和$http.post,所以,在所有的快捷方法内部都可以使用这个参数。你可以传递config对象来修改发送的请求,config对象可以设置以下键值。
method:一个字符串,表示HTTP请求的类型,例如GET或者POST。
url:URL字符串,表示请求的绝对或者相对资源路径。
params:一个键和值都是字符串的对象(确切来说是一个map),表示需要转换成URL参数的键和值。例如:
[{key1: 'value1', key2: 'value2'}]
将会被转换成
?key1=value&key2=value2
并会被附加到URL后面。如果我们使用js对象(而不是字符串或者数值)作为map中的值,那么这个js对象会被转换成JSON字符串。
data:一个字符串或者对象,它会被当作请求数据发送。
timeout:在请求超时之前需要等待的毫秒数。
二.设置HTTP头
AngularJS带有一些默认的请求头,Angular发出的所有请求上都会带有这些默认的请求头信息。默认请求头包括以下两个:
1.Accept:appliction/json,text/pain,/
2.X-Requested-With: XMLHttpRequest
如果想设置特殊的请求头,可以用如下两种方法实现。
第一种方法,如果你想把请求头设置到每一个发送出去的请求上,那么你可以把需要使用的特殊请求头设置成AngularJS的默认值。这些值可以通过$httpProvider.defaults.headers配置对象来设置,通常会在应用的配置部分来做这件事情。所以,如果你想对所有的GET请求使用“DO NOT TRACK"头,同时对所有请求删除Requested-With头,可以简单地操作如下:
[javascript] view plain copy print?
01.angular.module('MyApp', []).
02. config(function($httpProvider) {
03. //删除AngularJS默认的X-Request-With头
04. delete $httpProvider.default.headers.common['X-Requested-With'];
05. //为所有GET请求设置DO NOT TRACK
06. $httpProvider.default.headers.get['DNT'] = '1';
07.});
如果你只想对某些特定的请求设置请求头,但不把它们作为默认值,那么你可以把头信息作为配置对象的一部分传递给$http服务。同样的,自定义头信息也可以作为第二个参数的一部分传递给GET请求,第二个参数还可以同时接受URL参数。
$http.get('api/user', {
//设置Authorization(授权)头。在真实的应用中,你需要到一个服务里面去获取auth令牌
headers: {'Authorization': 'Basic Qzsda231231'},
params: {id:5}
}).success(function() {//处理成功的情况 });
三.缓存响应
对于HTTP GET请求,AngularJS提供了一个开箱即用的简单缓存机制。默认情况下它对所有请求类型都不可用,为了启用缓存,你需要做一些配置:
[javascript] view plain copy print?
01.$http.get('http://server/myapi', {
02. cache: true
03.}).success(function() {//处理成功的情况});
这样就可以启用缓存,然后AngularJS将会缓存来自服务器的响应。下一次向同一个URL发送请求的时候,AngularJS将会返回缓存中的响应内容。缓存也是智能的,所以即使你向同一个URL发送多次模拟的请求,缓存也只会向服务器发送一个请求,而且在收到服务端的响应之后,响应的内容会被分发给所有请求。
但是,这样做有些不太实用,因为用户会先看到缓存的旧结果,然后看到新的结果突然出现。例如,当用户即将点击一条数据时,它可能会突然发生变化。
注意,从本质上来说,响应(即使是从缓存中读取的)依然是异步的。换句话说,在第一次发出请求的时候,你应该使用处理异步请求的方式来编码。
四.转换请求和响应
对于所有通过$http服务发出的请求和收到的响应来说,AngularJS都会进行一些基本的转换,包括如下内容。
1.转换请求
如果请求的配置对象属性中包含JS对象,那么就把这个对象序列化成JSON格式。
2.转换响应
如果检测到了XSRF(Cross Site Request Forgery的缩写,意为跨站请求伪造,这是跨站脚本攻击的一种方式)前缀,则直接丢弃。如果检测到了JSON响应,则使用JSON解析器对它进行反序列化。
如果你不需要其中的某些转换,或者想自已进行转换,可以在配置项里面传入自已的函数。这些函数会获取HTTP的request/response体以及协议头信息,然后输出序列化、修改之后的版本。可以使用transformLRequest和transformResponse作为key来配置这些转换函数,而这两个函数在模块的config函数中是用$httpProvider服务来配置的。
我们什么时候需要使用这些东西呢?假设我们有一个服务,它更适合用jQuery的方式来操作。POST数据使用key1=val1&key2=val2(也就是字符串)形式来代替{key1:val1, key2:val2}JSON格式。我们可以在每个请求中来进行这种转换,也可以添加一个独立transformRequest调用,对于当前这个例子来说,我们打算添加一个通用的transformRequest,这样所有发出的请求都会进行这种从JSON到字符串的转换。下面就是实现方式:
[javascript] view plain copy print?
01.var module = angular.module('myApp');
02.
03.module.config(function($httpProvider) {
04. $httpProvider.defaults.transformRequest = function(data) {
05. //使用jQuery的param方法把JSON数据转换成字符串形式
06. return $.param(data);
07.
08. };
09.});
实列配置:
在使用中发现后台程序还是无法解析angular提交的数据,对比后发现头部缺少‘X-Requested-With’项
所以在配置中加入:$httpProvider.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest'
下面贴入测试时的部分配置代码:
[javascript] view plain copy print?
01.angular.module('app', [
02. 'ngAnimate',
03. 'ngCookies',
04. 'ngResource',
05. 'ngRoute',
06. 'ngSanitize',
07. 'ngTouch'
08.],function ($httpProvider) {
09. // 头部配置
10. $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
11. $httpProvider.defaults.headers.post['Accept'] = 'application/json, text/javascript, */*; q=0.01';
12. $httpProvider.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest';
13.
14. /**
15. * 重写angular的param方法,使angular使用jquery一样的数据序列化方式 The workhorse; converts an object to x-www-form-urlencoded serialization.
16. * @param {Object} obj
17. * @return {String}
18. */
19. var param = function (obj) {
20. var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
21.
22. for (name in obj) {
23. value = obj[name];
24.
25. if (value instanceof Array) {
26. for (i = 0; i < value.length; ++i) {
27. subValue = value[i];
28. fullSubName = name + '[' + i + ']';
29. innerObj = {};
30. innerObj[fullSubName] = subValue;
31. query += param(innerObj) + '&';
32. }
33. }
34. else if (value instanceof Object) {
35. for (subName in value) {
36. subValue = value[subName];
37. fullSubName = name + '[' + subName + ']';
38. innerObj = {};
39. innerObj[fullSubName] = subValue;
40. query += param(innerObj) + '&';
41. }
42. }
43. else if (value !== undefined && value !== null)
44. query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
45. }
46.
47. return query.length ? query.substr(0, query.length - 1) : query;
48. };
49.
50. // Override $http service's default transformRequest
51. $httpProvider.defaults.transformRequest = [function (data) {
52. return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
53. }];
54.}).config(function ($routeProvider) {
55. $routeProvider
56. .when('/', {
57. templateUrl: 'views/main.html',
58. controller: 'MainCtrl'
59. })
60. .when('/about', {
61. templateUrl: 'views/about.html',
62. controller: 'AboutCtrl'
63. })
64. .otherwise({
65. redirectTo: '/'
66. });
67. });
•$emit只能向parent controller传递event与data
•$broadcast只能向child controller传递event与data
•$on用于接收event与data
CSS中!important的使用
CSS的原理:
我们知道,CSS写在不同的地方有不同的优先级, .css文件中的定义 < 元素style中的属性,但是如果使用!important,事情就会变得不一样。
首先,先看下面一段代码:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>测试Css中的!Important区别</title>
</head>
<style type="text/css">
.testClass{
color:blue !important;
}
</style>
<body>
<div class="testClass" style="color:red;">
测试Css中的Important
</div>
</body>
</html>
虽然元素的style中有testClass类的定义,但是在上面的css定义中的用!important限定的定义却是优先级最高的,无论是在ie6-10或者Firefox和Chrome表现都是一致的,都显示蓝色。
这种情况也同时可以说明ie6是可以识别!important的,只是这个是ie6的一个缺陷吧。如果写成下面的样式,ie6是识别不出来的:
.testClass{
color:blue !important;
color:red;
}
这样,在ie6下展示的时候会显示成红色。
当然,也可以通过以下方式来让ie6识别:
.testClass{
color:blue !important;
}
.testClass{
color:red;
}
通过以上方式也是可以让ie6显示成蓝色的。
以上实例说明使用!important的css定义是拥有最高的优先级的。只是在ie6下出了一点小的bug,注意书写方式一般可以轻松避开的。
一、首先回顾一下有哪些绑定策略?
\
看这个实在是有点抽象了,我们来看具体的实例分析吧!
二、简单的Demo实例
@绑定:传递一个字符串作为属性的值。比如 str : ‘@string’
控制器中代码部分示例:
myDirec.controller('MyCtrl3',['$scope',function($scope){
$scope.ctrlFlavor=鸡尾酒;
$scope.sayHello=function(name){
alert(Hello +name);
};
}]);
myDirec.directive(drink,function(){
return{
restrict:'AE',
scope:{
flavor:'@' //自动绑定,传递的是字符串
},
template:
{{flavor}} , }; });
页面中使用标签部分示例:
分析我们在drink指令中为什么能取得在父作用域中的值呢?原因就在于我们使用了@绑定策略,可以将ctrlFlavor赋值给flavor,这样在模板中就能取到该值了。
=绑定:指定获取属性的类型为父作用域的属性
myDirec.directive(drink2,function(){
return{
restrict:'AE',
scope:{
flavor:'=' //自动绑定
},
template:'<input type="text" ng-model="flavor/">'
};
});
页面:
执行的流程是这样的:
① 指令被编译的时候会扫描到template中的模型发现有一个flavor,
② 查找scope中是否定义:通过=与父作用域绑定,方式是传递父作用域中的属性ctrlFlavor;
③ flavor与父作用域中的ctrlFlavor属性绑定,找到它的值“鸡尾酒”;
④ 将model的值显示在模板中。
&绑定:传递的是父作用域中的函数
控制器部分:
myDirec.directive(greeting, function() {
return {
restrict:'AE',
scope:{
greet:'&'
},
template:'<input type="text" ng-model="userName">
'+
'<button ng-click="greet({name:userName})">问候一下</button>
'
};
});
页面部分:
从结果上看,三个输入框中的内容互不影响,因为都是新的独立作用域,能够完成从视图到模型的绑定。
三、Expander示例
首先看控制器代码:
/*Expander示例*/
myDirec.controller('SomeController',function($scope) {
$scope.title = '点击展开';
$scope.text = '这里是内部的显示的内容';
});
myDirec.directive('expander', function() {
return {
restrict : 'EA',
replace : true,
transclude : true,
scope : {
title : '=expanderTitle'
},
template : '
' + '
{{title}} ' + '
' + ' ', link : function(scope, element, attrs) { scope.showMe = false; scope.toggle = function() { scope.showMe = !scope.showMe; }; } }; });
再看页面部分:
{{text}}
执行的流程是这样的:
① 指令被编译的时候会扫描到template中的模型发现有一个{{title}},
② 查找scope中是否定义:通过=与父作用域绑定,方式是传递父作用域中的属性;
我总是在这里犯糊涂,解释下这个“方式是传递父作用域中的属性”,这个在哪里用的呢?
{{text}} 看到没,指令中的属性expander-title='title',这不就是传递父作用域中的属性吗?
③ expander-title与父作用域中的title属性绑定,找到它的值“点击展开”;
④ 将title的值显示在模板中。
注意:指令中的独立作用域中的属性title是为了给下面的模板使用 的,而title所对应的值,要依据页面中指令的使用传人具体的父作用域中的属性,完成属性的绑定操作。
总之、我们可以利用angularjs为我们提供的数据绑定策略来实现从父作用域向指令中传值,这个很有用哦!
bootstrap学习:
http://www.runoob.com/bootstrap/bootstrap-tutorial.html
http://www.ibootstrap.cn/
angular在通过异步提交数据时使用了与jQuery不一样的请求头部和数据序列化方式,导致部分后台程序无法正常解析数据。
原理分析(网上的分析):
[javascript] view plain copy print?
01.<span style="font-size:14px;">对于AJAX应用(使用XMLHttpRequests)来说,向服务器发起请求的传统方式是:获取一个XMLHttpRequest对象的引用、发起请求、读取响应、检查状态码,最后处理服务端的响应。整个过程示例如下:</span>
[javascript] view plain copy print?
01.var xmlhttp = new XMLHttpRequest();
02.
03.xmlhttp.onreadystatechange = function() {
04. if(xmlhttp.readystate == 4 && xmlhttp.status == 200) {
05. var response = xmlhttp.responseText;
06. }else if(xmlhttp.status == 400) { //或者可以是任何以4开头的状态码
07. //优雅地处理错误
08. }
09.};
10.
11.//建立连接
12.xmlhttp.open("GET", "http://myserver/api", true);
13.
14.//发起请求
15.xmlhttp.send();
对于简单、常用而且会经常重复的任务来说,这是一种很烦琐的工作。如果你想复用以上过程,你应该进行封装或者使用代码库。
AngularJS XHR API遵守一种通常被称为Promise的接口。由于XHR是异步调用的方法,所以服务端的响应会在未来某个不确定的时间点上返回(我们希望它立即能返回)。Promise接口规定了处理这种响应的方式,并且允许Promise的使用者以一种可预见的方式来使用它。
例如,我们要从服务端获取一个用户的信息,假设用来接受请求的后台接口位于/api/user路径上,此接口可以接受一个id属性作为URL参数,那么使用Angular的核心$http服务发起XHR请求的方法示例如下:
[javascript] view plain copy print?
01.$http.get('api/user', {params: {id:'5'}
02.}).success(function(data, status, headers, config) {
03. //加载成功之后做一些事
04.}).error(function(data, status, headers, config) {
05. //处理错误
06.});
如果你是jQuery使用者,你应该会发现,AngularJS和jQuery在对异步请求的处理方面非常类似。
上面例子中使用的$http.get方法是AngularJS的核心服务$http所提供的众多快捷方法之一。类似地,如果你想使用AngularJS向同一个URL发送POST请求,同时带上一些POST数据,你可以像下面这样做:
[javascript] view plain copy print?
01.var postData = {text:'long blob of text'};
02.//下面这一行会被当成参数附加到URL后面,所以post请求最终会变成/api/user?id=5
03.var config = {params: {id: '5'}};
04.$http.post('api/user', postData, config
05.).success(function(data, status, headers, config) {
06. //成功之后做一些事情
07.}).error(function(data, status, headers, config) {
08. //处理错误
09.});
对于大多数常用的请求类型,都有类似的快捷方法,这些请求类型包括:GET、HEAD、POST、DELETE、PUT、JSONP。
一.进一步配置请求
虽然标准的请求方式使用起来比较简单,但是,有时候会存在可配置性不佳的缺点。如果你想要实现下面这些事情就会遇到困难:
a.给请求加上一些授权头。
b.修改对缓存的处理方式。
c.用一些特殊的方式来变换发送出去的请求,或者变换接收到的响应。
在这些情况下,你可以给请求传递一个可选的配置对象,从而对请求进行深度配置。在前面的例子中,我们使用config对象指定了一个可选的URL参数。但是那里的GET和POST方法是一些快捷方式。这种深度简化之后的方法调用示例如下:
$http(config)
下面是一个基本的伪代码模板,用来调用前面的这个方法:
[javascript] view plain copy print?
01.$http({
02. method: string,
03. url: string,
04. params: object,
05. data: string or object,
06. headers: object,
07. transformRequest: function transform(data, headersGetter) or an array of functions,
08. transformResponse: function transform(data, headersGetter) or an array of functions,
09. cache: boolean or Cache object,
10. timeout: number,
11. withCredentials: boolean
12.});
GET、POST及其他快捷方法都会自动设置method参数,所以不需要手动设置。config对象会作为最后一个参数传递给$http.get和$http.post,所以,在所有的快捷方法内部都可以使用这个参数。你可以传递config对象来修改发送的请求,config对象可以设置以下键值。
method:一个字符串,表示HTTP请求的类型,例如GET或者POST。
url:URL字符串,表示请求的绝对或者相对资源路径。
params:一个键和值都是字符串的对象(确切来说是一个map),表示需要转换成URL参数的键和值。例如:
[{key1: 'value1', key2: 'value2'}]
将会被转换成
?key1=value&key2=value2
并会被附加到URL后面。如果我们使用js对象(而不是字符串或者数值)作为map中的值,那么这个js对象会被转换成JSON字符串。
data:一个字符串或者对象,它会被当作请求数据发送。
timeout:在请求超时之前需要等待的毫秒数。
二.设置HTTP头
AngularJS带有一些默认的请求头,Angular发出的所有请求上都会带有这些默认的请求头信息。默认请求头包括以下两个:
1.Accept:appliction/json,text/pain,/
2.X-Requested-With: XMLHttpRequest
如果想设置特殊的请求头,可以用如下两种方法实现。
第一种方法,如果你想把请求头设置到每一个发送出去的请求上,那么你可以把需要使用的特殊请求头设置成AngularJS的默认值。这些值可以通过$httpProvider.defaults.headers配置对象来设置,通常会在应用的配置部分来做这件事情。所以,如果你想对所有的GET请求使用“DO NOT TRACK"头,同时对所有请求删除Requested-With头,可以简单地操作如下:
[javascript] view plain copy print?
01.angular.module('MyApp', []).
02. config(function($httpProvider) {
03. //删除AngularJS默认的X-Request-With头
04. delete $httpProvider.default.headers.common['X-Requested-With'];
05. //为所有GET请求设置DO NOT TRACK
06. $httpProvider.default.headers.get['DNT'] = '1';
07.});
如果你只想对某些特定的请求设置请求头,但不把它们作为默认值,那么你可以把头信息作为配置对象的一部分传递给$http服务。同样的,自定义头信息也可以作为第二个参数的一部分传递给GET请求,第二个参数还可以同时接受URL参数。
$http.get('api/user', {
//设置Authorization(授权)头。在真实的应用中,你需要到一个服务里面去获取auth令牌
headers: {'Authorization': 'Basic Qzsda231231'},
params: {id:5}
}).success(function() {//处理成功的情况 });
三.缓存响应
对于HTTP GET请求,AngularJS提供了一个开箱即用的简单缓存机制。默认情况下它对所有请求类型都不可用,为了启用缓存,你需要做一些配置:
[javascript] view plain copy print?
01.$http.get('http://server/myapi', {
02. cache: true
03.}).success(function() {//处理成功的情况});
这样就可以启用缓存,然后AngularJS将会缓存来自服务器的响应。下一次向同一个URL发送请求的时候,AngularJS将会返回缓存中的响应内容。缓存也是智能的,所以即使你向同一个URL发送多次模拟的请求,缓存也只会向服务器发送一个请求,而且在收到服务端的响应之后,响应的内容会被分发给所有请求。
但是,这样做有些不太实用,因为用户会先看到缓存的旧结果,然后看到新的结果突然出现。例如,当用户即将点击一条数据时,它可能会突然发生变化。
注意,从本质上来说,响应(即使是从缓存中读取的)依然是异步的。换句话说,在第一次发出请求的时候,你应该使用处理异步请求的方式来编码。
四.转换请求和响应
对于所有通过$http服务发出的请求和收到的响应来说,AngularJS都会进行一些基本的转换,包括如下内容。
1.转换请求
如果请求的配置对象属性中包含JS对象,那么就把这个对象序列化成JSON格式。
2.转换响应
如果检测到了XSRF(Cross Site Request Forgery的缩写,意为跨站请求伪造,这是跨站脚本攻击的一种方式)前缀,则直接丢弃。如果检测到了JSON响应,则使用JSON解析器对它进行反序列化。
如果你不需要其中的某些转换,或者想自已进行转换,可以在配置项里面传入自已的函数。这些函数会获取HTTP的request/response体以及协议头信息,然后输出序列化、修改之后的版本。可以使用transformLRequest和transformResponse作为key来配置这些转换函数,而这两个函数在模块的config函数中是用$httpProvider服务来配置的。
我们什么时候需要使用这些东西呢?假设我们有一个服务,它更适合用jQuery的方式来操作。POST数据使用key1=val1&key2=val2(也就是字符串)形式来代替{key1:val1, key2:val2}JSON格式。我们可以在每个请求中来进行这种转换,也可以添加一个独立transformRequest调用,对于当前这个例子来说,我们打算添加一个通用的transformRequest,这样所有发出的请求都会进行这种从JSON到字符串的转换。下面就是实现方式:
[javascript] view plain copy print?
01.var module = angular.module('myApp');
02.
03.module.config(function($httpProvider) {
04. $httpProvider.defaults.transformRequest = function(data) {
05. //使用jQuery的param方法把JSON数据转换成字符串形式
06. return $.param(data);
07.
08. };
09.});
实列配置:
在使用中发现后台程序还是无法解析angular提交的数据,对比后发现头部缺少‘X-Requested-With’项
所以在配置中加入:$httpProvider.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest'
下面贴入测试时的部分配置代码:
[javascript] view plain copy print?
01.angular.module('app', [
02. 'ngAnimate',
03. 'ngCookies',
04. 'ngResource',
05. 'ngRoute',
06. 'ngSanitize',
07. 'ngTouch'
08.],function ($httpProvider) {
09. // 头部配置
10. $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
11. $httpProvider.defaults.headers.post['Accept'] = 'application/json, text/javascript, */*; q=0.01';
12. $httpProvider.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest';
13.
14. /**
15. * 重写angular的param方法,使angular使用jquery一样的数据序列化方式 The workhorse; converts an object to x-www-form-urlencoded serialization.
16. * @param {Object} obj
17. * @return {String}
18. */
19. var param = function (obj) {
20. var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
21.
22. for (name in obj) {
23. value = obj[name];
24.
25. if (value instanceof Array) {
26. for (i = 0; i < value.length; ++i) {
27. subValue = value[i];
28. fullSubName = name + '[' + i + ']';
29. innerObj = {};
30. innerObj[fullSubName] = subValue;
31. query += param(innerObj) + '&';
32. }
33. }
34. else if (value instanceof Object) {
35. for (subName in value) {
36. subValue = value[subName];
37. fullSubName = name + '[' + subName + ']';
38. innerObj = {};
39. innerObj[fullSubName] = subValue;
40. query += param(innerObj) + '&';
41. }
42. }
43. else if (value !== undefined && value !== null)
44. query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
45. }
46.
47. return query.length ? query.substr(0, query.length - 1) : query;
48. };
49.
50. // Override $http service's default transformRequest
51. $httpProvider.defaults.transformRequest = [function (data) {
52. return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
53. }];
54.}).config(function ($routeProvider) {
55. $routeProvider
56. .when('/', {
57. templateUrl: 'views/main.html',
58. controller: 'MainCtrl'
59. })
60. .when('/about', {
61. templateUrl: 'views/about.html',
62. controller: 'AboutCtrl'
63. })
64. .otherwise({
65. redirectTo: '/'
66. });
67. });
发表评论
-
JS解析json数据(如何将json字符串转化为数组)
2018-01-11 09:56 848<!DOCTYPE HTML PUBLIC &quo ... -
bootstrap-datetimepicker 日期控件的开始日期
2017-09-22 00:59 1137今天做日期控件,需求要求设置一个时间范围限制,选择从今天开始 ... -
AngularJS ng-show 指令
2017-09-26 09:50 433http://www.runoob.com/angul ... -
js 判断数组中是否包含
2017-09-15 19:35 527可以使用数组的indexOf()方法,如果返回值为-1则说 ... -
jquery中html()、text()、val()的区别
2017-09-13 16:02 782.html()用为读取和修改元素的HTML标签 对应j ... -
grunt nodejs npm的关系是什么样的?
2017-09-11 15:03 552昨天自己鼓捣grunt,开始的时候不大明白,现在好像有种模糊 ... -
grunt安装及使用
2017-09-11 14:54 1223Grunt是什么? Grunt是一个基于JavaScri ... -
NPM是随同NodeJS一起安装的包管理工具
2017-09-11 14:22 578NPM 使用介绍 NPM是随同NodeJS一起安装的包管理 ... -
浅谈 Flash/Flex/HTML5 技术选型
2017-09-11 11:09 519在HTML5发布以前,RIA领 ... -
JSON数据的删除某个元素
2017-09-07 16:39 1099有一组JSON数据: var tempJSON = [{id ... -
JS异步加载的三种方式
2017-09-01 12:19 803一:同步加载 我们平时使用的最多的一种方式。 & ... -
Javascript异步编程的4种方法
2017-09-01 12:19 483你可能知道,Javascript ... -
AngularJS 实现按需异步加载实例代码
2017-09-01 12:19 763AngularJS 通过路由支持多视图应用, 可以根据路由 ... -
angularJS页面加载完成后调用,循环结束后调用
2017-08-31 19:19 1594angularJS页面加载完成后调用,代码如下 ... -
JS 跨域原因及其解决方案
2017-08-18 10:57 638产生跨域问题的原因 跨域问题是浏览器同源策略限制,当前域名 ... -
gRaphael——JavaScript 矢量图表库
2017-06-12 17:34 861gRaphael 是一个致力于帮 ... -
Raphael.js简易教程
2017-06-12 17:35 987Raphael.js 的教程非常简单,仅首页一段代码,然后 ... -
Zepto.js
2017-05-26 15:58 784Zepto是一个轻量级的针对现代高级浏览器的JavaScr ... -
阿里g2图表
2017-04-11 12:22 13351.百度的Echart ECharts,缩写来自Ente ... -
为什么js文件的名字像MD5运算过的一样?
2017-04-07 00:24 467这个过程叫做 revision。如果你有一个名字是 main ...
相关推荐
**AngularJS学习手册源代码详解** AngularJS,作为Google维护的一款强大的前端JavaScript框架,自2009年发布以来,已经在Web开发领域产生了深远影响。它通过MVC(Model-View-Controller)架构模式,提供了丰富的...
**AngularJS 框架详解** AngularJS 是一个强大的JavaScript框架,由Google维护,用于构建动态Web应用。它通过MVC(模型-视图-控制器...通过深入学习和实践,你可以有效地利用AngularJS构建高效、可维护的Web应用程序。
### 四、AngularJs学习笔记 学习笔记通常包含个人对AngularJS理解的深入点,可能包括一些高级话题,如脏检查(Dirty Checking)、$digest循环,以及如何优化性能。笔记可能还包括解决常见问题的方法,以及作者在...
AngularJS的学习资料众多,其中"AngularJS学习 chm 文件"是一个方便快捷的学习资源。 CHM文件,全称是Compiled HTML Help,是一种由Microsoft开发的帮助文件格式。它将HTML页面、索引和图像等资源打包在一起,形成...
### AngularJS学习笔记知识点解析 #### 一、AngularJS简介 AngularJS是由Google推出的一款JavaScript库,虽然在本文档中作者将其称为“工具”,但实际上它更接近于一个完整的前端开发框架。AngularJS的设计理念...
### AngularJS 学习资料详解 #### 一、AngularJS简介与重要性 AngularJS是一种广泛使用的开源前端JavaScript框架,由Google维护。它主要用于构建单页面应用(SPA),通过简化客户端和服务器之间的交互来提高用户...
AngularJS是google在维护,其在国外已经十分火热,可是国内的使用情况却有不小的差距,参考文献/网络文章也...这里便将我学习AngularJS写成文档,一方面作为自己学习路程上的记录,另一方面也给有兴趣的同学一些参考。
**AngularJS学习笔记** AngularJS,作为一款强大的前端JavaScript框架,由Google维护,主要用于构建单页应用程序(SPA)。它的核心特性包括数据绑定、依赖注入、模块化和指令系统,极大地简化了网页应用的开发流程...
这个压缩包包含了AngularJS学习的全链条资料,无论你是初学者还是有一定经验的开发者,都能从中受益。通过系统学习和实践,你将能够熟练掌握AngularJS,构建出功能强大、用户体验优良的Web应用。
AngularJS 是一个 JavaScript框架。它是一个以 JavaScript 编写的库。它可通过 [removed] 标签添加到HTML 页面。 AngularJS 通过 指令 扩展了 HTML,且通过 表达式 绑定数据到 HTML。 AngularJS 是以一个 JavaScript...
### AngularJS 学习笔记 #### 一、AngularJS 概述 AngularJS 是一个用于构建动态Web应用的开源框架,由 Google 维护。它通过扩展 HTML 的功能来简化 Web 开发,并允许开发者以声明式的方式编写代码,极大地提高了...
angularjs学习需要导入的angular.js
AngularJS,是由Google...总之,这个压缩包中的资料是一个全面的AngularJS学习资源库,无论你是初学者还是有一定经验的开发者,都能从中找到有价值的信息,提升你的AngularJS技能。祝你在学习的道路上取得丰硕的成果!
在《AngularJS学习笔记.chm》中,读者可以期待找到关于这些概念的深入解释,包括如何创建AngularJS项目,设置模块,编写控制器,使用指令,以及进行数据绑定和依赖注入的实例。此外,还可能涉及如何调试、优化...
总而言之,这份AngularJS的学习笔记为初学者提供了一个由浅入深、涵盖AngularJS基础知识和核心概念的全面指南。通过对这份笔记的学习,初学者可以逐步掌握AngularJS的使用,从而有效地进行前端开发。
AngularJS学习总结 AngularJS是一款功能强大且流行的前端JavaScript框架,用于构建复杂的Web应用程序。通过学习AngularJS,可以快速熟悉前端编程,实现快速开发高质量的Web应用程序。 一、引入AngularJS 要使用...
**AngularJS权威学习指南手册** AngularJS是一款由Google维护的前端JavaScript框架,它极大地简化了构建动态Web应用的复杂性。本指南专为初学者设计,旨在帮助他们快速理解和掌握AngularJS的核心概念和技术。 **一...
AngularJS学习总结&详细介绍 AngularJS是一款流行的前端JavaScript框架,用于构建单页应用程序(Single Page Application,简称SPA)。下面是AngularJS学习经验总结,全中文说明: 什么是AngularJS? AngularJS...