咱们知道默认的路由提供(Route Provider)在复杂的应用程序中是不太适合应用场景,它存在诸多限制,因此在Angular 1.2以后此时咱们不得不将路由提供做为一个单独的模块当咱们须要使用时即ngRoute,可是该ngRoute使用起来仍是不够灵活,AngularJS团队很快意识到了这点,因而提出了ui.router做为ngRoute的完美替代品。javascript
此节咱们要讨论关于Route的高级,也就是深刻探讨AngularUi Router中的比较高级的内容,关于ui.router有以下强大特色:html
(1)嵌套状态和嵌套视图。java
(2)多个命名视图(由一个视图到另一个视图经过引用视图的名称)。设计模式
(3)嵌套解析(一个解析等待另一个解析完毕)。api
(4)ui.sref指令(绑定超连接,并自动生成)。跨域
......promise
对于本节咱们则要讲述的是路由的resolve,在ngRoute中也存在resolve,ui.router中的resolve相比较更增强大,因而对于ngRoute中的Resolve未作过多探讨,有兴趣的童鞋能够自行去学习,那resolve究竟是作什么的?它能够在一个路由中提早加载数据,接着这个resolve中的属性会被注入到此路由的控制器中,ui.router中的reolve应该是该路由模块中最大的特性。当resolve中的所有属性被解析完毕时,resolve才会执行,意味着是延迟执行。下面咱们来一步一步看看resolve。浏览器
经过在resolve中经过函数返回一个字符串,此时会当即被解析。咱们来看看。app
<html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript" src="../Scripts/angular.min.js"></script> <script src="../ui-router/angular-ui-router.min.js"></script> <script src="app.js"></script> </head> <body ng-app="app"> <div ui-view></div> </body> </html>
angular.module("app",["ui.router"]) .config(config); function config($stateProvider,$urlRouterProvider){ $urlRouterProvider.otherwise("/resolve"); $stateProvider.state("resolve",{ url:"/resolve", templateUrl:"resolve.html", resolve: { cnblogs:function(){ return "xpy0928"; } }, controller: function($scope, cnblogs){ $scope.loadData = cnblogs; } }); }
咱们接着在视图resolve.html中显示绑定的数据 {{loadData}} 结果毫无疑问显示xpy0928。ide
上述咱们是在视图内部定义的控制器从而绑定数据,若是咱们的Application足够大,此时路由势必会膨胀,在这种状况下,咱们仍是单独定义控制器并绑定数据,以下:
function config($stateProvider,$urlRouterProvider){ $urlRouterProvider.otherwise("/resolve"); $stateProvider.state("resolve",{ url:"/resolve", templateUrl:"resolve.html", controller:"resolveVM", resolve: { cnblogs:function(){ return "xpy0928"; } } }); } angular.module("app").controller("resolveVM",function($scope,cnblogs){ $scope.loadData = cnblogs; });
同时咱们也应该注意,当咱们没有宿主运行时,对于有些浏览器可能会出现违背了跨域,在AnuglarJS中启动跨域,能够进行以下操做:
$httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With'];
上述对于简单使用resolve给出了一个基本的例子,咱们再往下面看看。
咱们首先看看一个最简单返回promise的例子。咱们只需在上述app.js中的resolve进行以下修改:
resolve: { promiseObj: function($http){ return $http({method: 'GET', url: ''}); },
貌似仍是不太乐观,下面咱们详细介绍下,通常对于resolve无非就是经过resource即http请求来返回数据固然或者经过服务来获取数据。上述是咱们简单的返回一个promise,咱们彻底能够自定义一个promise。将resolve修改以下:
resolve: { delayedData: function($q, $timeout) { var deferred = $q.defer(); $timeout(function() { var myData = {message: 'hello,everyone!xpy0928 from cnblogs'}; deferred.resolve(myData); }, 1000); return deferred.promise; } }
接下来咱们来绑定数据:
angular.module("app").controller("resolveVM",function($scope,delayedData){ $scope.loadData = delayedData; });
诶,貌似没图,仍是演示下:
上述有说过咱们利用resolve无非根据http获取数据,在AngularJS中利用ngResource来实现(推荐前面的替代品,这里只是做为演示用)。
咱们以下修改resolve:
resolve: { userData: function(userList) { var list = userList.query(); return list.$promise; } }
建立获取用户列表服务:
angular.module("app").factory('userList', ['$resource', function ($resource) { return $resource('http://localhost:52005/api/cnblogs/getUserlist'); }]); angular.module("app").controller("resolveVM",function($scope,userData){ $scope.loadData = userData; });
咱们看下效果:
上述只是利用resolve解析一个promise,若咱们要在路由或者状态发生改变以前解析多个promise,此时咱们该如何作?咱们此时利用$q.all开完成,咱们来看以下代码:
resolve: { userData: function($q,userList,blogList) { var list = userList.query(); var bloglist = blogList.query(); return $q.all([list.$promise,blogList.$promise]) .then(function(){ }) } }
经过resource获取数据:
angular.module("app").factory('userList', ['$resource', function ($resource) { return $resource('http://localhost:52005/api/cnblogs/getUserlist'); }]); angular.module("app").factory('blogList', ['$resource', function ($resource) { return $resource('http://localhost:52005/api/cnblogs/getBloglist'); }]);
如上,就是这么简单。
本节咱们讲了路由中比较高级的知识resolve,建议在实际开发中利用ui.router来完成而非ngRouter中的resolve,同时本节也涉及到了$q/promise,本节未进行详细阐述,下节咱们咱们仔细讲讲$q或者其余知识。
本打算再写一篇关于promise的文章,搜到一篇写的很是好的文章,那就再也不讲述了连接以下:
AngularJS 中的Promise和设计模式: http://my.oschina.net/ilivebox/blog/293771?p=1