ui-router

Edit

所谓的Single Page Application (SPA)的核心就是用ui-router来切换不同的UI state,从而实现页面功能。但是相关库并不在AngularJS中,有两个库用的比较多

  • ngRouter from Google and community
  • ui-router from community

本文基于后者。

How to use it?

<script src="lib/angular.min.js"></script>
<script src="lib/angular-ui-router.min.js"></script>
<ui-view></ui-view>
angular.module('App',['ui.router']);

ui-router会用template html来替换ui-view标签<ui-view></ui-view>
进入核心配置:

angular.module('App')
.config(RoutesConfig);
RoutesConfig.$inject =
['$stateProvider', '$urlRouterProvider'];
function RoutesConfig($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/view1');
$stateProvider
.state('view1', {
url: '/view1',
template: '<div>…</div>'
})
.state('view2', {...});
}

$urlRouterProvider.otherwise设置了默认的URL。$stateProvider设置了各个状态。

$stateProvider
.state('itemDetail', {
url: '',
templateUrl: '',
controller: 'ItemListController as itemList',
resolve: {
}

每个状态都可以有template和controller。

controller

controller成员有这么几种写法:

  • controller: ‘CtrlName as label’
  • controller: CtrlName
  • controllerAs: label

resolve

The resolve property is a map object. The map object contains key/value pairs of:

  • key – {string}: a name of a dependency to be injected into the controller.
  • factory - {string|function}:
    • If string, then it is an alias for a service.
    • Otherwise if function, then it is injected and the return value is treated as the dependency. If the result is a promise, it is resolved before the controller is instantiated and its value is injected into the controller.。

Yaakov的课程此处可能有错讹。并不是什么都能往resolve里放,放数字会报错,具体可参看GitHub - angular-ui/ui-router

也就是factory只有两种可能,string或者function,如果直接放数字,会出错。resolve成员会在controller实例化之前被确定。如果promise被reject,则会取消状态切换,然后错误会被送到$stateChangeError。resolve的成员,通过inject可以被controller使用,如下:

View1Ctrl.$inject = ['myData'];
function View1Ctrl(myData) {
var view1 = this;
view1.myData = myData;
}

URL Parameters

.state('view1', {
url: '/view1/{param1}',
templateUrl: 'view1.html',
controller: 'View1Ctrl as view1',
resolve: {
myData: ['$stateParams',
function ($stateParams) {
return getDataBasedOn($stateParams.param1);
}]
}
});

这是最正常的写法。在HTML中如下使用:

<a ui-sref="view1({itemId:someVal})">
Link to view with data
</a>

或者

$state.go('contacts', {param1: value1})

正则参数

Examples:

  • /user/{id:[^/]*} - Same as ‘/user/{id}’ from the previous example.
  • /user/{id:[0-9a-fA-F]{1,8}} - Similar to the previous example, but only matches if the id parameter consists of 1 to 8 hex digits.
  • /files/{path:.*} - Matches any URL starting with ‘/files/’ and captures the rest of the path into the parameter ‘path’.
  • /files/*path - Ditto. Special syntax for catch all.

目前,尚未实践过,猜测是对URL进行捕获,如果不符合该正则表达式,则该参数不存在

多于1个参数
使用URL参数写法:url: "/contacts?myParam1&myParam2"

Using Parameters without Specifying Them in State URLs

.state('contacts', {
url: "/contacts",
params: {
param1: null
},
templateUrl: 'contacts.html'
})

Router State Transition Events

stateChangeSuccess - fired once the state transition is complete
$stateChangeError - fires when an error occurs during transition
event.preventDefault() - to prevent the transition from occurring

State Inheritance

状态也可以继承,继承的唯一目的就是使用嵌套的ui-view。

.state('view1', {
resolve: {
myData: 'someVal';
}
})
.state('view1.child', {
url: '/detail/{param1}',
templateUrl: 'view1Detail.html',
controller: "ChildCtrl as child"
});
ChildCtrl.$inject = ['myData'];
function ChildCtrl (myData) { … }

状态继承的时候,resolve成员也可以继承,如上。

%23%20ui-router%0A@%28myblog%29%5Bangular%5D%0A%0A%u6240%u8C13%u7684Single%20Page%20Application%20%28SPA%29%u7684%u6838%u5FC3%u5C31%u662F%u7528ui-router%u6765%u5207%u6362%u4E0D%u540C%u7684UI%20state%uFF0C%u4ECE%u800C%u5B9E%u73B0%u9875%u9762%u529F%u80FD%u3002%u4F46%u662F%u76F8%u5173%u5E93%u5E76%u4E0D%u5728AngularJS%u4E2D%uFF0C%u6709%u4E24%u4E2A%u5E93%u7528%u7684%u6BD4%u8F83%u591A%0A-%20ngRouter%20from%20Google%20and%20community%0A-%20ui-router%20from%20community%0A%0A%u672C%u6587%u57FA%u4E8E%u540E%u8005%u3002%0A%0A%23%23%20How%20to%20use%20it%3F%0A%60%60%60%0A%3Cscript%20src%3D%22lib/angular.min.js%22%3E%3C/script%3E%0A%3Cscript%20src%3D%22lib/angular-ui-router.min.js%22%3E%3C/script%3E%0A%0A%3Cui-view%3E%3C/ui-view%3E%0A%0Aangular.module%28%27App%27%2C%5B%27ui.router%27%5D%29%3B%0A%60%60%60%0Aui-router%u4F1A%u7528template%20html%u6765%u66FF%u6362ui-view%u6807%u7B7E%60%3Cui-view%3E%3C/ui-view%3E%60%u3002%0A%u8FDB%u5165%u6838%u5FC3%u914D%u7F6E%uFF1A%0A%60%60%60%0Aangular.module%28%27App%27%29%0A.config%28RoutesConfig%29%3B%0ARoutesConfig.%24inject%20%3D%0A%5B%27%24stateProvider%27%2C%20%27%24urlRouterProvider%27%5D%3B%0Afunction%20RoutesConfig%28%24stateProvider%2C%20%24urlRouterProvider%29%20%7B%0A%09%24urlRouterProvider.otherwise%28%27/view1%27%29%3B%0A%09%0A%09%24stateProvider%0A%09.state%28%27view1%27%2C%20%7B%0A%09%09url%3A%20%27/view1%27%2C%0A%09%09template%3A%20%27%3Cdiv%3E%u2026%3C/div%3E%27%0A%09%7D%29%0A%09.state%28%27view2%27%2C%20%7B...%7D%29%3B%0A%7D%0A%60%60%60%0A%60%24urlRouterProvider.otherwise%60%u8BBE%u7F6E%u4E86%u9ED8%u8BA4%u7684URL%u3002%60%24stateProvider%60%u8BBE%u7F6E%u4E86%u5404%u4E2A%u72B6%u6001%u3002%0A%0A%60%60%60%0A%24stateProvider%0A.state%28%27itemDetail%27%2C%20%7B%0A%20%20%20%20url%3A%20%27%27%2C%0A%20%20%20%20templateUrl%3A%20%27%27%2C%0A%20%20%20%20controller%3A%20%27ItemListController%20as%20itemList%27%2C%0A%20%20%20%20resolve%3A%20%7B%0A%20%20%20%20%7D%0A%60%60%60%0A%u6BCF%u4E2A%u72B6%u6001%u90FD%u53EF%u4EE5%u6709template%u548Ccontroller%u3002%0A%0A%23%23%23%20controller%0Acontroller%u6210%u5458%u6709%u8FD9%u4E48%u51E0%u79CD%u5199%u6CD5%uFF1A%0A-%20controller%3A%20%u2018CtrlName%20as%20label%u2019%0A-%20controller%3A%20CtrlName%0A-%20controllerAs%3A%20label%0A%0A%23%23%23%20resolve%0AThe%20resolve%20property%20is%20a%20map%20object.%20The%20map%20object%20contains%20key/value%20pairs%20of%3A%0A%0A-%20key%20%u2013%20%7Bstring%7D%3A%20a%20name%20of%20a%20dependency%20to%20be%20injected%20into%20the%20controller.%0A-%20factory%20-%20%7Bstring%7Cfunction%7D%3A%0A%09-%20If%20string%2C%20then%20it%20is%20an%20alias%20for%20a%20service.%0A%09-%20Otherwise%20if%20function%2C%20then%20it%20is%20injected%20and%20the%20return%20value%20is%20treated%20as%20the%20dependency.%20If%20the%20result%20is%20a%20promise%2C%20it%20is%20resolved%20before%20the%20controller%20is%20instantiated%20and%20its%20value%20is%20injected%20into%20the%20controller.%u3002%0A%0A%0A*Yaakov%u7684%u8BFE%u7A0B%u6B64%u5904%u53EF%u80FD%u6709%u9519%u8BB9%u3002%u5E76%u4E0D%u662F%u4EC0%u4E48%u90FD%u80FD%u5F80resolve%u91CC%u653E%uFF0C%u653E%u6570%u5B57%u4F1A%u62A5%u9519%uFF0C%u5177%u4F53%u53EF%u53C2%u770B%5BGitHub%20-%20angular-ui/ui-router%5D%28https%3A//github.com/angular-ui/ui-router/wiki%29*%0A%0A%u4E5F%u5C31%u662Ffactory%u53EA%u6709%u4E24%u79CD%u53EF%u80FD%uFF0Cstring%u6216%u8005function%uFF0C%u5982%u679C%u76F4%u63A5%u653E%u6570%u5B57%uFF0C%u4F1A%u51FA%u9519%u3002resolve%u6210%u5458%u4F1A%u5728controller%u5B9E%u4F8B%u5316%u4E4B%u524D%u88AB%u786E%u5B9A%u3002%u5982%u679Cpromise%u88ABreject%uFF0C%u5219%u4F1A%u53D6%u6D88%u72B6%u6001%u5207%u6362%uFF0C%u7136%u540E%u9519%u8BEF%u4F1A%u88AB%u9001%u5230%24stateChangeError%u3002resolve%u7684%u6210%u5458%uFF0C%u901A%u8FC7inject%u53EF%u4EE5%u88ABcontroller%u4F7F%u7528%uFF0C%u5982%u4E0B%3A%0A%60%60%60%0AView1Ctrl.%24inject%20%3D%20%5B%27myData%27%5D%3B%0Afunction%20View1Ctrl%28myData%29%20%7B%0A%09var%20view1%20%3D%20this%3B%0A%09view1.myData%20%3D%20myData%3B%0A%7D%20%0A%60%60%60%0A%0A%23%23%23%20URL%20Parameters%0A%60%60%60%0A.state%28%27view1%27%2C%20%7B%0A%09url%3A%20%27/view1/%7Bparam1%7D%27%2C%0A%09templateUrl%3A%20%27view1.html%27%2C%0A%09controller%3A%20%27View1Ctrl%20as%20view1%27%2C%0A%09resolve%3A%20%7B%0A%09%09myData%3A%20%5B%27%24stateParams%27%2C%0A%09%09%09function%20%28%24stateParams%29%20%7B%0A%09%09%09return%20getDataBasedOn%28%24stateParams.param1%29%3B%0A%09%09%7D%5D%0A%09%7D%0A%7D%29%3B%0A%60%60%60%0A%u8FD9%u662F%u6700%u6B63%u5E38%u7684%u5199%u6CD5%u3002%u5728HTML%u4E2D%u5982%u4E0B%u4F7F%u7528%uFF1A%0A%60%60%60%0A%3Ca%20ui-sref%3D%22view1%28%7BitemId%3AsomeVal%7D%29%22%3E%0A%09Link%20to%20view%20with%20data%0A%3C/a%3E%0A%60%60%60%0A%u6216%u8005%0A%60%60%60%0A%24state.go%28%27contacts%27%2C%20%7Bparam1%3A%20value1%7D%29%0A%60%60%60%0A%0A**%u6B63%u5219%u53C2%u6570**%0A%3EExamples%3A%0A%0A%3E-%20%60/user/%7Bid%3A%5B%5E/%5D*%7D%60%20-%20Same%20as%20%27/user/%7Bid%7D%27%20from%20the%20previous%20example.%0A%3E-%20%60/user/%7Bid%3A%5B0-9a-fA-F%5D%7B1%2C8%7D%7D%60%20-%20Similar%20to%20the%20previous%20example%2C%20but%20only%20matches%20if%20the%20id%20parameter%20consists%20of%201%20to%208%20hex%20digits.%0A%3E-%20%60/files/%7Bpath%3A.*%7D%60%20-%20Matches%20any%20URL%20starting%20with%20%27/files/%27%20and%20captures%20the%20rest%20of%20the%20path%20into%20the%20parameter%20%27path%27.%0A%3E-%20%60/files/*path%60%20-%20Ditto.%20Special%20syntax%20for%20catch%20all.%0A%0A*%u76EE%u524D%uFF0C%u5C1A%u672A%u5B9E%u8DF5%u8FC7%uFF0C%u731C%u6D4B%u662F%u5BF9URL%u8FDB%u884C%u6355%u83B7%uFF0C%u5982%u679C%u4E0D%u7B26%u5408%u8BE5%u6B63%u5219%u8868%u8FBE%u5F0F%uFF0C%u5219%u8BE5%u53C2%u6570%u4E0D%u5B58%u5728*%0A%0A**%u591A%u4E8E1%u4E2A%u53C2%u6570**%0A%u4F7F%u7528URL%u53C2%u6570%u5199%u6CD5%uFF1A%60url%3A%20%22/contacts%3FmyParam1%26myParam2%22%60%0A%0A**Using%20Parameters%20without%20Specifying%20Them%20in%20State%20URLs**%0A%60%60%60%0A.state%28%27contacts%27%2C%20%7B%0A%09url%3A%20%22/contacts%22%2C%0A%20%20%20%20params%3A%20%7B%0A%20%20%20%20%20%20%20%20param1%3A%20null%0A%20%20%20%20%7D%2C%0A%20%20%20%20templateUrl%3A%20%27contacts.html%27%0A%7D%29%0A%60%60%60%0A%0A%23%23%20Router%20State%20Transition%20Events%0A%24stateChangeStart%20-%20fires%20when%20state%20change%20transition%20begins%0A%24stateChangeSuccess%20-%20fired%20once%20the%20state%20transition%20is%20complete%0A%24stateChangeError%20-%20fires%20when%20an%20error%20occurs%20during%20transition%0Aevent.preventDefault%28%29%20-%20to%20prevent%20the%20transition%20from%20occurring%0A%0A%23%23%20State%20Inheritance%0A%u72B6%u6001%u4E5F%u53EF%u4EE5%u7EE7%u627F%uFF0C%u7EE7%u627F%u7684%u552F%u4E00%u76EE%u7684%u5C31%u662F%u4F7F%u7528%u5D4C%u5957%u7684ui-view%u3002%0A%60%60%60%0A.state%28%27view1%27%2C%20%7B%0A%09resolve%3A%20%7B%0A%09%09myData%3A%20%27someVal%27%3B%0A%09%7D%0A%09%u2026%0A%7D%29%0A.state%28%27view1.child%27%2C%20%7B%0A%09url%3A%20%27/detail/%7Bparam1%7D%27%2C%0A%09templateUrl%3A%20%27view1Detail.html%27%2C%0A%09controller%3A%20%22ChildCtrl%20as%20child%22%0A%09%u2026%0A%7D%29%3B%0AChildCtrl.%24inject%20%3D%20%5B%27myData%27%5D%3B%0Afunction%20ChildCtrl%20%28myData%29%20%7B%20%u2026%20%7D%0A%60%60%60%0A%u72B6%u6001%u7EE7%u627F%u7684%u65F6%u5019%uFF0Cresolve%u6210%u5458%u4E5F%u53EF%u4EE5%u7EE7%u627F%uFF0C%u5982%u4E0A%u3002%0A