咱們知道默認的路由提供(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