angular-按需加载angularjs和$http.post的二三事
来源:互联网 发布:淘宝买iphone8靠谱吗 编辑:程序博客网 时间:2024/06/16 07:00
最近前端比较火的框架,可数facebook的react了,一个专门针对移动端开发的前端高性能框架。当然google的angularjs也是一个很火的前端框架,在SPA应用上算是非常出色的。具体的基础入门大家可以看看菜鸟网络的http://www.runoob.com/angularjs/angularjs-tutorial.html,这里都是一些基本知识点
下面要说的是,我本人在应用angular中遇到的一些问题和平时用jquery实现的方式的异同。
(1)单页面应用中加载有关angualr的js文件
在进入单页面的初始化时,所有用到的angualr的js需要一次性加载,不能做到按需加载。
比如在路由中,我们设置了很多的不同页面和对应路由,那么进入不同的路由,我们就需要按需加载不同的的angualr的controller的js文件了。如果我们在页面中直接通过<script src="./test.js"></script>加载angular的这个test.js文件时,这个只会通过xhr的异步对象请求方式加载进来的,test.js文件时加载进来了,但是它并没有将view视图中双向绑定那样,把请求返回来的数据通过$scope的作用域绑定显示出来。具体的原因是因为通过xhr异步加载的test.js文件已将是处于angular的上下文之外了,说的简单点,即是处于两个不同的环境域中,所以对于数据绑定也就是model来说,这个过程是跨域的,不会发生的。(AngularJS 上下文之外的任何地方修改了 model ,那么你就需要通过手动调用 $apply() 来通知 AngularJS 。这就像告诉 AngularJS ,你修改了一些 models ,希望 AngularJS 帮你触发 watchers 来做出正确的响应)。当然如果是普通的js文件,这是可以加载并且可以执行的。
那么对于这种情况,我们应该怎么解决呢?因为在单页应用中,当功能越来越多,越来越复杂的时候,我们就需要按需来加载不同路由下的js文件了!下面,我在github上找到一个比较好的开源的解决方案!
官网:https://oclazyload.readme.io/docs/oclazyloadprovider
ui-router的演示:http://plnkr.co/edit/u18KQc?p=preview
那么我们可以npm install oclazyload 安装
var app = angular.module('app', ['ngRoute','oc.lazyLoad']);app.config(['$routeProvider',function($routeProvider) {$routeProvider.when('/main', {templateUrl: '/home/index/main',controller: 'MainCtrl'}).when('/dashboard', {templateUrl: '/home/index/view',controller: 'DashboardCtrl', resolve: { loadMyCtrl:['$ocLazyLoad',function ($ocLazyLoad) { return $ocLazyLoad.load({ name:"view", files:["/static/js/angular-gridster/demo/dashboard/script.js"] }); }] }}).otherwise({redirectTo: '/main'});}])其中最重要就是
resolve: { loadMyCtrl:['$ocLazyLoad',function ($ocLazyLoad) { return $ocLazyLoad.load({ name:"view", files:["/static/js/angular-gridster/demo/dashboard/script.js"] }); }] }这个resove 是在执行路由渲染模板前进行一个操作,resove里面的值由key:value组成,key的值可以自定义,基本模式就是这样子,return 回来一个promise.
所以按照上面的路由配置就可以方便实现按需动态加载,可以给我们的开发带来更加清晰的过程。
angular本身的ng-router在功能上还是受限,建议如果要用路由的话,可以用开源的angular-ui-router,这个功能强大,而且可以多个层级的路由,模板嵌套等。
安装angular-ui-router 直接用npm install angular-ui-router
(2)angular的$http.post(),传输json数据格式问题
在实际项目中,我们遇到了一个很常见问题,当使用
$http.post(url,{'name':'bing','sex':1}).success(function(response){
});
post一个json数据过去的时候,在服务端php(或者一些其他语言),当我们用$_POST的时候,却没有办法获取到这个json数据。
因为按照我们平时在用jquery的时候
$.post({
url:...,
data:{'name':'bing','sex':1},
.....
});
同样也是这样子,一般是可以成功的将数据post到服务端的,为什么angualr就不可以呢?
在httpd通信的请求中,发送请求时,可以通过content-type指定请求体的发包是以何种格式来实现的!
application/x-www-form-urlencoded是标准的表单发包方式,普通的表单提交,或者js发包,默认都是通过这种方式实现的。也就是说post方法的请求体内容数据最终必须转成application/x-www-form-urlencoded,也就是'name=bing&sex=1',服务端才可以通过$_POST获取到数据。
那么jquery为什么可以呢?
下面看一下jquery的官方说明:
data:将自动转换为请求字符串格式。GET 请求中将附加在 URL 后面。查看 processData 选项说明,以禁止此自动转换。对象必须为"{键:值}"格式。如果这个参数是一个数组,jQuery会按照traditional 参数的值, 将自动转化为一个同名的多值查询字符串(查看下面的说明)。注:如 {foo:["bar1", "bar2"]} 转换为 'foo=bar1&foo=bar2'。
也就是说jquery会自动将json数据格式转为字符串格式后(序列化后),再进行post的传输发包。
而在angualr中,请求post过去的json数据并不会转为name=bing&sex=1这种格式的字符串,而是默认就是json,但由于http通信中并没有所谓的json,所有在传输的时候,也就是,application/json可以将它理解为text/plain,普通字符串。那么不满足发包的格式。自然在服务端$_POST就没法接收数据了。
具体的解决办法:
(1)利用jquery的$.param()方法
var queryData = $.param({'name':'bing','sex':1}); $http({ url : 'test.php', method : 'POST', data : queryData, headers : {'Content-Type':'application/x-www-form-urlencoded'}, }).success(function(response) { });其中headers : {'Content-Type':'application/x-www-form-urlencoded'}需要设置。
有人说,缺点就是引入jquery,但本人认为在一个应用系统中,大部分都会使用jquery的,angular和jquery相互结合开发,才是强强组合。
而且$.param()处理对象序列化的层数更深层,这个也是非常方便。
(2)利用angular自身封装的$httpParamSerializer()
{'foo': 'bar'}
results infoo=bar
{'foo': Date.now()}
results infoo=2015-04-01T09%3A50%3A49.262Z
(toISOString()
and encoded representation of a Date object){'foo': ['bar', 'baz']}
results infoo=bar&foo=baz
(repeated key for each array element){'foo': {'bar':'baz'}}
results infoo=%7B%22bar%22%3A%22baz%22%7D
(stringified and encoded representation of an object)
https://docs.angularjs.org/api/ng/service/$httpParamSerializerJQLike
一种使用方法
$http({ url: myUrl, method: 'GET', params: myParams, paramSerializer: '$httpParamSerializerJQLike'});
另一种使用方法.controller(function($http, $httpParamSerializerJQLike) { //... $http({ url: myUrl, method: 'POST', data: $httpParamSerializerJQLike(myData), headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });});
(3)自己重新定义序列化
var ballApp = angular.module('BallApp', [], function($httpProvider) { // 修改 header $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; // Serialize function //只能是嵌套两层的对象 var param = function(obj) { var query = '', name, value, fullSubName, subName, subValue, innerObj,i; for(name in obj) { value = obj[name]; //如果值是数组 if(value instanceof Array) { for(i = 0; i < value.length; ++i) { subValue = value[i]; fullSubName = name + '[' + i + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += param(innerObj) + '&'; } //如果值是对象 } else if(value instanceof Object) { for(subName in value) { subValue = value[subName]; fullSubName = name + '[' + subName + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += param(innerObj) + '&'; } 如果值是字符串 } else if(value !== undefined && value !== null) { query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; } } return query.length ? query.substr(0, query.length - 1) : query; } //重写transformRequest参数处理方法(利用param function 处理) $httpProvider.defaults.transformRequest = [function(data) { return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data; }];});ballApp.controller('AjaxCtrl', function($scope, $http) { $scope.ajax = function() { $http.post('test.php', {name: 'Febr'}) .success(function(data) { console.log(data); }); };});
如果您觉得本文对你有帮助,那就按按鼠标,顶一下,让更多的人可以看到它......
- angular-按需加载angularjs和$http.post的二三事
- angularjs的$http.post和$http.get的使用
- angularjs $http实现get和post请求
- 【js类库AngularJs】解决angular+springmvc的post提交问题
- 【js类库AngularJs】解决angular的post提交问题
- 【js类库AngularJs】解决angular+springmvc的post提交问题
- AngularJS封装$http.post()
- angularJS 发起$http.post和$http.get请求
- angularjs $http.get 和 $http.post 传递参数
- angularJS 发起$http.post和$http.get请求
- angularjs $http.get 和 $http.post 传递参数
- AngularJS中的$http.post与jQuery.post的区别
- AngularJS中的$http.post与jQuery.post的区别
- angular $http post数据和jQuerypost数据不一样
- angular $q封装$http get和post请求
- 修改 Jquery Ajax post数据和 angular $http服务一致
- angular和jquery的post请求方式
- angular http post后端无法获取数据的解决方案
- CDISC SDTM MI domain学习笔记
- php 使用ajax文本框模糊查询
- “J.U.C”:Phaser (r)
- ASP.NET 5 Dependency Injection with Autofac
- iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用
- angular-按需加载angularjs和$http.post的二三事
- iOS App Crash日志
- 解决了一个连接mysql特别慢的问题
- 时间日期类详解--Calendar
- BZOJ 1057 [ZJOI2007]棋盘制作
- kvc与kvo
- SpiderMonkey-让你的C++程序支持JavaScript脚本
- iOS 切换语言开发 中英文切换
- “J.U.C”:CAS操作 (r)