ui-router和同属性的AngularJS框架一部分的ng-route一样强大。ui-router提供了让我们可以做路由嵌套和视图命名的特征。
实战
一般针对需求,我们可以使用AngularJS框架来创建简单的html和JavaScript页面。下面我们将创建3个HTML页面和一个JavaScript脚本文件
一开始我们创建一个空的web应用程序,并加入三个HTML页面。如下所示,这些页面都是片段视图。它们会在导航过程中展示。我们还要为能展示应用程序的Tab,创建另外一个叫做PageTab.html的页面
因此我们先创建以下文件:
1,Page1.html
2,Page2.html
3,Page3.html
4,PageTab.html
Page1.html
创建如下的html页面:
<div>
<div>
<h>我踏遍轮回,只为与你相遇</h1>
</div>
</div>
Page2.html
创建如下的html页面:
<div>
<div>
<h>我要这天再也遮不住我的眼</h1>
</div>
</div>
Page3.html
创建如下的html页面:
<div>
<div>
<h>要这地再也埋不住我的身</h1>
</div>
</div>
PageTab.html
创建如下的html页面:
<div>
<div>
<span style="width:100px"><a href="">Page-1</a></span>
<span style="width:100px"><a href="">Page-2</a></span>
<span style="width:100px"><a href="">Page-3</a></span>
</div>
</div>
这将会使页面文本处在侧边,并添加当用户鼠标悬停在文本上的时候的超链接。
我们没有指向任何超链接,只是为了把链接放在href中,实际上这是一种获取url的解决方式
到目前为止,我们还没有插入任何AngularJS路由或者其它任何框架。目前我们只是创建了一些页面片段,我们需要一个占位或者说父页面来装下这些东西,我们可以将这个页面起名为Main.html
Main.html
用如下内容创建这个html页面
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-ui-router.js"></script>
<script src="App.js"></script>
</head>
<body data-ng-app="myApp">
<h>AngularJS Home Page (Ui-router Demostration)</h1>
<div data-ui-view=""></div>
</body>
<html>
我们需要在主页上做一些事情,(1)我们需要引入AngularJS框架(2)需要引入ui-router框架(3)引入AngularJS文件App.js(4)让主页内容展示出来,然后显示出它里面的页面
而App.js文件的内容,我们声明了AngularJS模块和路由配置。当页面加载的时候我们会在Main.html中显示PageTab.html的内容。代码如下
App.js
var myApp=angular.module("myApp",['ui.router']);
myApp.config(function($stateProvider,$urlRouterProvider){
$urlRouterProvider.when("","/PageTab");
$stateProvide
.state("PageTab",{
url:"/PageTab",
templateUrl:"PageTab.html"
})
.state("PageTab.Page1",{
url:"/Page1",
templateUrl:"Page-1.html"
})
.state("PageTab.Page2",{
url:"/Page2",
templateUrl:"Page-2.html"
})
.state("PageTab.Page3",{
url:"/Page3",
templateUrl:"Page-3.html"
});
});
现在来解释这些步骤都是干啥的
代码行
1,第一行,声明AngularJS模块,并把ui-router传入AngularJS主模块,所有的结合起来我们就得到了Angular模块
var myApp=angular.module("myApp",['ui.router']);
这里叫做App模块,这将告诉HTML页面这是一个AgularJS作用的页面,它的内容有AngularJS引擎来解释
2,这一行声明了把$stateProvider和$urlRouterProvider路由引擎作为函数参数传入,这样我们就可易为这个应用程序配置路由了
myApp.config(function($stateProvider,$urlRouterProvider){
3,下面一行的意思是:如果没有路由引擎能匹配当前的导航状态,那它就会默认将路径路由至PageTab.html,这个页面就是状态名称被声明的地方。只要理解了这个,那么它就像switch case语句中的default选项
$urlRouterProvider.when("","/PageTab");
语句块
1,这一行定义了会在Main.html页面第一个显示出来的状态,作为页面被加载好以后第一个被使用的路由
$stateProvide
.state("PageTab",{
url:"/PageTab",
templateUrl:"PageTab.html"
})
这就是向母版页的子页面,应用程序会首先加载这个main.html页面
2,现在,就由这一行来定义页面,但是,这里又有点不同,我们之前为上面的状态名称加上了前缀,并且使用点"."号进行了分隔,这里很关键,它会告诉路由引擎我们在这里定义的是子页面/嵌入页面/嵌入状态的page/route.
.state("PageTab.Page2",{
url:"/Page2",
templateUrl:"Page-2.html"
})
它将会在"PageTab.html"页面显示出来,它的意思是:当我们想要在母版页中管理所有的页面时,我们就会想要一个叫做"ui-view"的占位标记。因此我们现在把PageTab.html佳作一个母版页,因为它会把我们需要在PageTab.html中用"ui-view"声明好的其它页面都管理起来。现在我们再来修改这段代码
PageTab.html
<div>
<div>
<span style="width:100px"><a href="">Page-1</a></span>
<span style="width:100px"><a href="">Page-2</a></span>
<span style="width:100px"><a href="">Page-3</a></span>
</div>
<div>
<div ui-view="" />
</div>
</div>
下面一行:
<div>
<div ui-view="">
</div>
也就是说PageTab.html将对装下所有的子页面
现在一切就绪,但是页面应该显示哪个页面呢。这就是我们要在路由引擎里面配置的东西,如下所示
.state("PageTab.Page2",{
url:"/Page2",
templateUrl:"Page-2.html"
})
Page2.html将会在被叫做PageTab的状态中显示,它就是PageTab.html
但是我们还落下啥事没做,这事就是当我们在 Page-1 或者 Page-2 再或者 Page-3 菜单上点击的时候需要页面在占位标记那里显示出来,是不 ?
还真是把那一块给忘啦,我们还没有为路由和这种逻辑建立起联系, 想象一下如果那是href的话,就意味着我们可以指定将会锚向页面里面的ID名称, 如果它是简单的html本地引用就是这样,但我们则需要按照需求显示不同的页面.
关键的地方在这里. (ui-sref) 我们需要再一次修改 PageTab.html,如下所示.,
<div>
<div>
<span style="width:100px" ui-sref=".Page1"><a href="">Page-1</a></span>
<span style="width:100px" ui-sref=".Page2"><a href="">Page-2</a></span>
<span style="width:100px" ui-sref=".Page3"><a href="">Page-3</a></span>
</div>
<div>
<div ui-view="" />
</div>
</div>
注意,只是上面高亮的部分发生了改变 , 这里我们只是简单的将App.js中定义的状态同tab中定义的对应文本进行了关联. 当我们使用点符号对它进行了声明,程序就会认为页面时ui-view中的子页面或者说嵌入页面,它们就是路由配置中需要被展示的页面.
AngularJS ui-router-组件:
$state/$stateProvider:管理状态定义,当前状态和状态的转换。包含触发状态转换的事件和回调函数,异步解决目标状态的任何依赖项,更新$location到当前状态。由于状态包含关联的url,通过$urlRouterProvider生成一个路由规则来执行转换的状态。
ui-view指示器:渲染状态中定义的视图,是状态中定义的视图的一个占位符。
$urlRouter/$urlRouterProvider:管理了一套路由规则列表来处理当$location发生变化时,如何跳转。最低级的方式是,规则可以是任意函数,来检查$location,并在处理完成时返回true。支持正则表达式规则和通过$urlMatcherFactory编译的UrlMatcher对象的url占位符规则。
$urlMatcherFactory:将url和占位符编译为UrlMatcher对象。除了$routeProvider支持的占位符语法之外,它还支持扩展语言,允许一个正则表达式指定占位符,并且能够提取命名参数和查询url的一部分。$templateFactory-通过$http/$templateCache来加载模块,供状态配置中使用
关于嵌套路由
所谓嵌套路由,就是视图里还可以再嵌套视图,路由里还可以在嵌套路由,并且通过ui-router,可以实现不同视图之间的参数传递
关于ui-router的简单使用
ui-router定义路由的时候,与ngRouter不一样,它是使用.来进行定义的,并且在html标签中,不使用ng-view,而是使用ui-view,比如:<div ui-view></div>
ui-router提供了$stateProvider,$urlRouterProvider来定义路由,具体使用如下:
/* 使用ui-router来进行路由定义,需要注入ui.router模块 */
var myApp = angular.module('myApp', ['ui.router']);
/* 注入$stateProvider,$urlRouterProvider */
myApp.config(['$stateProvider', '$urlRouterProvider', function ( $stateProvider, $urlRouterProvider ) {
/* 使用when来对一些不合法的路由进行重定向 */
$urlRouterProvider.when('', '/main');
/* 通过$stateProvider的state()函数来进行路由定义 */
$stateProvider.state('main', {
url: '/main',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
}).state('detail', {
url: '/main/detail/store',
templateUrl: 'views/detail.html',
controller: 'DetailCtrl'
})
$stateProvider.state('404', {
url: '/404',
templateUrl: '404.html'
})
}]);
ui-router-路由控制$stateProvider
在我们的应用中大多数状态都有与其相关联的url,路由控制不是设计完成state之后的事后想法,而是在开始开发时就应该考虑的问题
如何设置一个基本的url:
$stateProvider
.state('contacts',{
url:"/contacts",
templateUrl:'contacts.html'
})
当我们访问index.html/contacts时,‘contacts’状态将被激活,同时index.html中的ui-view将被‘contacts.html’填充。或者,通过transitionTo('contacts')方法将状态转变到‘contacts’状态,同时url将更新为index.html/contacts。
状态被激活时,它的模板会自动插入到父状态对应的模块中包含ui-view属性的元素内部。如果是顶层的状态,那么它的父模板就是index.html
激活状态
有三种方法来激活状态:
1调用$state.go()方法,这是一个高级的遍历方法
2点击包含ui-sref指令链接
3导航到与状态相关连的url
Templates模块
可以通过下面几种方式来配置一个状态的模块
方法一
配置template属性,指定一段HTML字符串,这是设置模块的最简单打方式
$stateProvider.state('contact',{
template:'<h1>my contacts<h1>'
})
方法二
配置templateUrl属性,来加载到指定位置的模块,这就是设置模块的常用方法
$stateProvider.state('contacts',{
templateUrl:'contacts.html'
})