参考原文:https://github.com/angular-ui/ui-router/wiki 
ui-router 的工作原理非常类似于 Angular 的路由控制器,但它只关注状态。
在应用程序的整个用户界面和导航中,一个状态对应于一个页面位置 
通过定义controller、template和view等属性,来定义指定位置的用户界面和界面行为 
通过嵌套的方式来解决页面中的一些重复出现的部位 
 
最简单的形式 模板可以通过下面这种最简单的方式来指定
1 2 3 4 <body  ng-controller ="MainCtrl" >     <section  ui-view > </section >  </body > 
 
1 2 3 4 $stateProvider.state ('contacts' , {   template : '<h1>My Contacts</h1>'  }) 
 
 
模板将被插入哪里? 状态被激活时,它的模板会自动插入到父状态对应的模板中包含ui-view属性的元素内部。如果是顶层的状态,那么它的父模板就是index.html。
激活状态 有三种方法来激活状态:
调用$state.go()方法,这是一个高级的便利方法; 
点击包含ui-sref指令的链接; 
导航到与状态相关联的 url。 
 
Templates 模板 可以通过下面几种方法来配置一个状态的模板。
方法一:配置template属性,指定一段 HTML 字符串,这人是设置模板的最简单的方式
1 2 3 $stateProvider.state ('contacts' , {   template : '<h1>My Contacts</h1>'  }) 
 
方法二:配置templateUrl属性,来加载指定位置的模板,这是设置模板的常用方法。 
1 2 3 $stateProvider.state ('contacts' , {   templateUrl : 'contacts.html'  }) 
 
templateUrl的值也可以是一个函数返回的url,函数带一个预设参数stateParams。
1 2 3 4 5 $stateProvider.state ('contacts' , {   templateUrl : function  (stateParams ){     return  '/partials/contacts.'  + stateParams.filterBy  + '.html' ;   } }) 
 
方法三:通过templateProvider函数返回模板的 HTML。
1 2 3 4 5 6 7 $stateProvider.state ('contacts' , {   templateProvider : function  ($timeout, $stateParams ) {     return  $timeout(function  ( ) {       return  '<h1>'  + $stateParams.contactId  + '</h1>'      }, 100 );   } }) 
 
如果想在状态被激活前,让<ui-view>有一些默认的内容,当状态被激活之后默认内容将被状态对应的模板替换。
1 2 3 4 5 <body >     <ui-view >          <i > Some content will load here!</i >      </ui-view >  </body > 
 
Controllers 控制器 可以为模板指定一个控制器(controller)。警告 :控制器不会被实例化如果模板没有定义。
设置控制器:
1 2 3 4 5 6 $stateProvider.state ('contacts' , {   template : '<h1>{{title}}</h1>' ,   controller : function ($scope ){     $scope.title  = 'My Contacts' ;   } }) 
 
如果在模块中已经定义了一个控制器,只需要指定控制器的名称即可:
1 2 3 4 $stateProvider.state ('contacts' , {   template : ...,   controller : 'ContactsCtrl'  }) 
 
使用controllerAs语法:
 1 2 3 4 $stateProvider.state ('contacts' , {   template : ...,   controller : 'ContactsCtrl as contact'  }) 
 
对于更高级的需要,可以使用controllerProvider来动态返回一个控制器函数或字符串:
 1 2 3 4 5 6 7 $stateProvider.state ('contacts' , {   template : ...,   controllerProvider : function ($stateParams ) {       var  ctrlName = $stateParams.type  + "Controller" ;       return  ctrlName;   } }) 
 
控制器可以使用$scope.on()方法来监听事件状态转换。
控制器可以根据需要实例化,当相应的scope被创建时。例如,当用户点击一个url手动导航一个状态时,$stateProvider将加载对应的模板到视图中,并且将控制器和模板的scope绑定在一起。
解决器 Resolve 可以使用resolve为控制器提供可选的依赖注入项。
resolve配置项是一个由key/value构成的对象。
key – {string}:注入控制器的依赖项名称。 
factory - {string|function}:
string:一个服务的别名 
function:函数的返回值将作为依赖注入项,如果函数是一个耗时的操作,那么控制器必须等待该函数执行完成(be resolved)才会被实例化。 
 
 
 
例子 在controller实例化之前,resolve中的每一个对象都必须 be resolved,请注意每个 resolved object 是怎样作为参数注入到控制器中的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 $stateProvider.state ('myState' , {       resolve :{                              simpleObj :  function ( ){             return  {value : 'simple!' };          },                                        promiseObj :  function ($http ){                          return  $http({method : 'GET' , url : '/someUrl' });          },                                        promiseObj2 :  function ($http ){             return  $http({method : 'GET' , url : '/someUrl' })                .then  (function  (data ) {                    return  doSomeStuffFirst (data);                });          },                                                translations : "translations" ,                              translations2 : function (translations, $stateParams ){                                                        translations.getLang ($stateParams.lang );          },                    greeting : function ($q, $timeout ){              var  deferred = $q.defer ();              $timeout(function ( ) {                  deferred.resolve ('Hello!' );              }, 1000 );              return  deferred.promise ;          }       },              controller : function ($scope, simpleObj, promiseObj, promiseObj2, translations, translations2, greeting ){                      $scope.simple  = simpleObj.value ;                      $scope.items  = promiseObj.items ;           $scope.items  = promiseObj2.items ;           $scope.title  = translations.getLang ("english" ).title ;           $scope.title  = translations2.title ;           $scope.greeting  = greeting;       }    }) 
 
为 $state 对象提供自定义数据 可以给 $state 对象提供自定义数据(建议使用data属性,以免冲突)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var  contacts = {     name : 'contacts' ,     templateUrl : 'contacts.html' ,     data : {         customData1 : 5 ,         customData2 : "blue"      }   } $stateProvider   .state (contacts)   .state ('contacts.list' , {     templateUrl : 'contacts.list.html' ,     data : {         customData1 : 44 ,         customData2 : "red"      }    }) 
 
可以通过下面的方式来访问上面定义的数据:
1 2 3 4 function  Ctrl ($state ){    console .log ($state.current .data .customData1 )      console .log ($state.current .data .customData2 )  } 
 
onEnter 和 onExit 回调函数 onEnter和onExit回调函数是可选配置项,分别称为当一个状态变得活跃的和不活跃的时候触发。回调函数也可以访问所有解决依赖项。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $stateProvider.state ("contacts" , {   template : '<h1>{{title}}</h1>' ,   resolve : { title : 'My Contacts'  },   controller : function ($scope, title ){     $scope.title  = 'My Contacts' ;   },      onEnter : function (title ){      if (title){ ... do  something ... }   },      onExit : function (title ){     if (title){ ... do  something ... }   } }) 
 
State Change Events 状态改变事件 所有这些事件都是在$rootScope作用域触发
$stateChangeStart  - 当模板开始解析之前触发 
 
1 2 $rootScope.$on('$stateChangeStart' ,  function (event, toState, toParams, fromState, fromParams ){ ... })
 
注意:使用event.preventDefault()可以阻止模板解析的发生
1 2 3 4 5 6 $rootScope.$on('$stateChangeStart' ,  function (event, toState, toParams, fromState, fromParams ){     event.preventDefault ();            }) 
 
$stateNotFound  - v0.3.0 - 在 transition 时通过状态名查找状态,当状态无法找到时发生。该事件在 scope 链上广播,只允许一次处理错误的机会。unfoundState将作为参数传入事件监听函数,下面例子中可以看到unfoundState的三个属性。使用 event.preventDefault() 来阻止模板解析, 
 
1 2 3 4 5 6 7 8 9 10 $state.go ("lazy.state" , {a :1 , b :2 }, {inherit :false }); $scope.$on('$stateNotFound' ,  function (event, unfoundState, fromState, fromParams ){     console .log (unfoundState.to );      console .log (unfoundState.toParams );      console .log (unfoundState.options );  }) 
 
$stateChangeSuccess  - 当模板解析完成后触发 
 
1 2 $rootScope.$on('$stateChangeSuccess' ,  function (event, toState, toParams, fromState, fromParams ){ ... })
 
$stateChangeError  - 当模板解析过程中发生错误时触发 
 
1 2 $rootScope.$on('$stateChangeError' ,  function (event, toState, toParams, fromState, fromParams, error ){ ... })
 
View Load Events 视图加载事件 
$viewContentLoading  - 当视图开始加载,DOM渲染完成之前触发,该事件将在$scope链上广播此事件。 
 
1 2 3 4 5 6 $scope.$on('$viewContentLoading' ,  function (event, viewConfig ){                }); 
 
$viewContentLoaded  - 当视图加载完成,DOM渲染完成之后触发,视图所在的$scope发出该事件。 
 
1 2 3 $scope.$on('$viewContentLoading' ,  $scope.$on('$viewContentLoaded' ,  function (event ){ ... });