微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

angularjs学习3

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,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,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,config) { 06. //成功之后做一些事情 07.}).error(function(data,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,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. });

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐