(以下是自己的一些学习笔记,希望通过整理笔记的形式加深对zh的理解。如果内容有误,感谢指出。)
为什么使用前端路由
1、AJAX请求不会留下History记录(当URL改变时,需要将其增加到浏览器的历史记录中,防止按回退按钮不会破坏路由)
2、用户无法直接通过 URL 进入应用中的指定页面(保存书签、链接分享给朋友)
3、AJAX 对 SEO 是个灾难
二者简介
ngRoute模块是 Angular 自带的路由模块,而ui-router模块是基于ngRoute模块开发的第三方模块。
ngRoute是基于url(href="url")的,当请求一个url时,根据路由配置匹配这个url,然后请求模板片段,并插入到 ng-view 中去。而ui-router是基于state(ui-sref="state")的。相比之下,ui-router模块具有更强大的功能,在业界也更受欢迎,主要体现在ui-router的两方面特性:多样化视图和嵌套式视图(此部分参考原文:http://www.funnyant.com/angularjs-ui-router/)。
1、多样化视图:
大多数的应用程序会将页面布局为几个页面区块,如header部分、main-content部分和footer部分:
而AngularJS 的内置路由ngRoute只允许一个视图(ng-view)出现在页面上。这样限制的情况下,人们可以使用包含页面(ng-include)或者其他的变通方法为应用创建一个布局(layout)或主页(master page)。
ui-router支持多样化视图,并且每一个视图都有自己相应的控制,所以每个区块都是封装好,可以复用到整个应用程序需要的地方。
2、嵌套式视图:
嵌入式视图,顾名思义,就是不仅能够让几个视图同时出现,还能让一个视图嵌入到另一个视图中。
常见的嵌入式页面例子是列表的详情页面。许多应用程序,都有列表页面,点击其中一个列表元素,可以进入到列表的详情页面或是一个可编辑的表单。
如果列表页面和详情页面是单独分开的,使用AngularJS的内置路由ngRoute是非常容易完成的。
然而,如果你想要保持列表不变,而详情页面出现在列表的右边或者下面,这样就变得非常麻烦了:你需要让两个控制器(一个用于列表,一个用于显示和隐藏详情)共享一个视图。这样的结果不是理想的,因为我们想要列表和详情页面有各自的控制器和视图,并且职责单一(显示列表或者显示列表项目的详情)。而封装这些用户接口模块到它们各自的视图,这样我们就有更多的“可组合UI”,允许我们将各个区块整合到一起,或者根据需求拆分。
基本使用方法
demo1—最简单的ngRoute例子:
在index.html中引入angular.js和angular-route.js,以及我们自己定义的js文件。使用ng-view(单一视图)定义一个路由模板的视图层,不同路由对应的模板将会插入到这个 ngView 所在的dom元素下。
<span style="font-size:14px;color:#333333;"><!doctype html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-route.js"></script> <script src="app.js"></script> <script src="hello.js"></script> <script src="about.js"></script> </head> <body ng-app="routingApp"> <header> <a href="#/hello">Hello</a> <a href="#/about">About</a> </header> <!-- Place where our view will be displayed --> <div ng-view> </div> </body> </html></span>
在app.js文件中,通过$routeProvider内置服务进行路由配置,为每一个url(只能通过url导航)绑定一个template以及controller。( when(‘path’, {controller: xxx, templayeUrl: ‘xxx’}) 或 otherwise({redirectTo: ‘xxx’}) )
<span style="font-size:14px;color:#333333;">angular.module('routingApp', ['ngRoute']) // Setting configuration for application .config(function ($routeProvider) { $routeProvider.when('/hello', { controller: helloCtrl, templateUrl: 'hello.html' }).when('/about', { controller: aboutCtrl, templateUrl: 'about.html' }); }) // Ignore code below. This is usually in seperate html files .run(function ($templateCache){ $templateCache.put('hello.html', '<h1>{{message}}!</h1>'); $templateCache.put('about.html', '<h1>About</h1><p>{{description}}</p>'); });</span>
另外两个js文件如下,每个路由的controller中完成对应的业务逻辑:
<span style="font-size:14px;color:#333333;">function helloCtrl ($scope) { $scope.message = "Hello world"; }</span>
<span style="font-size:14px;color:#333333;">function aboutCtrl ($scope) { $scope.description = "This is an example application"; }</span>
demo2 —最简单的ui-router例子:
可以在demo1的基础上进行修改,文件目录一致,改动的地方如下:
首先是index.html文件,需要引入angular-ui-router.js文件。原来的href=‘url’改为ui-sref='state',用于装载视图的ng-view改为ui-view(一个页面可以有多个ui-view)
<span style="font-size:14px;color:#333333;"><!doctype html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-route.js"></script> <script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script> <script src="app.js"></script> <script src="hello.js"></script> <script src="about.js"></script> </head> <body ng-app="routingApp"> <header> <a ui-sref="hello">Hello</a> <a ui-sref="about">About</a> </header> <!-- Place where our view will be displayed --> <div ui-view> </div> </body> </html></span>
在app.js文件中,将ngRoute替换成ui.router模块(注意是ui.router不是ui-router,一个小坑),通过$stateProvider配置状态表。
<span style="font-size:14px;color:#333333;">var app= angular.module('routingApp', ['ui.router']); // Setting configuration for application app.config(['$stateProvider', '$urlRouterProvider',function($stateProvider, $urlRouterProvider) { // $urlRouterProvider.otherwise('/'); $stateProvider .state('hello', { url: '/hello', controller: helloCtrl, templateUrl: 'hello.html' }) .state('about', { url: '/about', controller: aboutCtrl, templateUrl: 'about.html' }); }]) // Ignore code below. This is usually in seperate html files .run(function ($templateCache){ $templateCache.put('hello.html', '<h1>{{message}}!</h1>'); $templateCache.put('about.html', '<h1>About</h1><p>{{description}}</p>'); });</span>
其他
1、ui-router通过ui-view实现多样化视图(ui-view='区块名')。Eg:
<div ui-view='header'></div> <div ui-view='content'></div> <div ui-view='footer'></div>
.state('home', { url: '/', views: { 'herder': { templateUrl: 'partials/header.html', controller: 'HeaderCtrl' }, 'content': { templateUrl: 'partials/content.html', controller: 'ContentCtrl' }, 'footer': { templateUrl: 'partials/footer.html', controller: 'FooterCtrl' } } });
2、ui-router通过 “父状态名.子状态名” 实现嵌入
式视图;通过独立的状态名“子状态名”实现解耦合。(例子略)
3、js页面跳转逻辑:$state.go('statename', {param: value});