这里是修真院前端小课堂,每篇分享文从javascript
【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】html
八个方面深度解析前端知识/技能,本篇分享的是:前端
【angularJS的两种路由ng-router和ui-router的差别】vue
你们好,我是IT修真院深圳分院第07期学员,一枚正直善良的web程序员。html5
今天给你们分享一下,修真院官网 JS-06任务中可能会使用到的知识点:java
1.背景介绍
angular路由nginx
AngularJS 路由容许咱们经过不一样的 URL 访问不一样的内容。程序员
经过 AngularJS 能够实现多视图的单页Web应用(single page web application,SPA)。angularjs
说了那么多,那么,什么是路由呢?web
AngularJs中的路由,应用比较普遍,主要是容许咱们经过不一样的url访问不一样的内容,可实现多视图的单页web应用。下面看看具体怎么使用。
一般咱们的URL形式为http://jtjds.cn/first/page,但在单页web应用中angularjs经过#+标记实现,好比下面的页面,将是下文中的路由列子:
http://192.168.1.109:8000/angular-program/src/main.html#/pagetable/page1
http://192.168.1.109:8000/angular-program/src/main.html#/pagetable/page2
http://192.168.1.109:8000/angular-program/src/main.html#/pagetable/page3
当咱们点击以上任一一个连接时,向服务器请求的地址都是http://192.168.1.109:8000/angular-program/src/main.html ,而#号以后的内容在向服务器端请求时会被浏览器忽略掉,因此咱们在客户端实现#号后面的功能实现便可。简单来讲,路由经过#+标记帮助咱们区分不一样逻辑页面,并将其绑定到对应的控制器上。
路由介绍
每一个页面均有一个控制器控制,经过路由,从而将不一样的页面展现出来。
二.知识剖析
ng-Route使用方法
1)引入 angular-route lib
不管是 ngRoute 仍是 ui.router ,做为框架额外的附加功能,都必须以 模块依赖 的形式被引入,并且要注意,须要先引用angular,这是由于angular-router.js须要传入window.angular这个参数,这个参数只有在加载angular才会出现。
<script src="../../bower_components/angular/angular.js"></script> <script src="lib/angular-route.js"></script> 2)配置路由 var app = angular.module('ngRouteApp', ['ngRoute']); app.config(function($routeProvider){ $routeProvider .when('/Main', { templateUrl: "main.html", controller: 'MainCtrl' }) .otherwise({ redirectTo: '/tabs' });
服务与指令
ngRoute 路由模块名
$routeProvider 服务提供者,用来定义一个路由表,即地址栏与视图模板的映射,对应于 ui.router 中的 urlRouterProvider 和 stateProvider
$route 服务,完成路由匹配,而且提供路由相关的属性访问及事件,如访问当前路由对应的 Controller,对应于下面的 $urlRouter 和 $state
$routeParams 服务,保存了地址栏中的参数,对应于下面的 $stateParams
ng-view 指令,用来在主视图中指定加载子视图的区域,对应于下面的 ui-view
ui-router使用方法
1)引入js文件
<script type="text/javascript" src="JS/angular.min.js"></script> <script type="text/javascript" src="JS/angular-ui-router.min.js"></script>
2)注入ui-router模块
var app = angular.module('myApp', ['ui.router']); app.config(function($urlRouterProvider, $stateProvider) { $urlRouterProvider.otherwise("/index"); //这条是至关于报错的时候跳转 $stateProvider .state("Main", { url: "/main", templateUrl: "main.html", controller: 'MainCtrl' })
服务与指令
ui.router 路由模块名 $urlRouterProvider 服务提供者,用来配置路由重定向 $stateProvider 服务提供者,用来配置路由 $urlRouter 服务 $state 服务,用来显示当前路由状态信息,以及一些路由方法(如:跳转) $stateParams 服务,用来存储路由匹配时的参数 ui-view 指令,路由模板渲染,对应的 dom 相关联 ui-sref 指令,连接到特定状态
三.常见问题
多视图
多样化视图.jpg
大多数的应用程序均可以分解为一个一个区块。最简单的状况,一个应用程序有头部(header),主体内容(main content area),以及一个尾部(footer)。
一般一个应用程序会有一个额外的侧边栏(sidebar )在页面的左边或者右边。
大多数用例中,这些区块将同时显示在页面上。Angular.js 的内置路由ngRoute只容许一个视图(ng-view)出如今页面上。
<div ng-view></div> <div ng-view></div>
由于ng-router没法命名ng-view,而ui-router则能够经过命名ui-view来实现显示不一样的视图出如今页面上
//html部分 <div ui-view></div> <div ui-view="login"></div> //js部分 .state("login.page1",{ url:"/page1", views:{ '':{template:"page2"}, 'login':{template:"hello"} } })
能够给视图命名,如:ui-view=”status”。
能够在路由配置中根据视图名字(如:status),配置不一样的模板(其实还有controller等)。
嵌套视图
嵌套视图:页面某个动态变化区块中,嵌套着另外一个能够动态变化的区块。
嵌入式视图.jpg
其实,嵌套视图,在html中的最终表现就像这样:
<div ng-view> session <div ng-view>article</div> </div> 转成javascript,咱们会在程序里这样写: .when('/error', { template: '<div ng-view>error</div>' }) </code>
一运行,报了一个这样的错误:
RangeError: Maximum call stack size exceeded
发现浏览器崩溃了,由于 ng-view 会陷入死循环,无限递归下去。
使用 ui.router 能很容易解决这个问题,由于它定义的路由有明确的父子关系,并经过 ui-view 指令将子路由模版插入到父路由模板的ui-view中去,从而实现视图嵌套。看代码:
$stateProvider .state("login",{ url:"/login", templateUrl:"login.html" //controller: 'loginCtr' //选择控制器 也能写成 loginCtr as login }) .state("login.page1",{ url:"/page1", template:"page1" }) .state("login.page2",{ url:"/page2", template:"page2" }) .state("login.page3",{ url:"/page3", template:"page3" })
四.解决方案
须要澄清的是,这样的要求可使用ngRoute来完成。可是你须要让两个控制器(一个用于列表,一个用于显示和隐藏详情)共享一个视图。这样的结果不是理想的,由于咱们想要列表和详情页面有各自的控制器和视图,而且职责单一(显示列表或者显示列表项目的详情)。封装这些用户接口模块到它们各自的视图,这样咱们就有更多的“可组合UI”,容许咱们将各个区块整合到一块儿,或者根据需求拆分。嵌入式视图,不只可以让这些视图同时出现,还能让一个视图嵌入到另外一个视图中。
五.代码实战
六.拓展思考
单页web应用(SPA)的简单介绍
单页 Web 应用 (single-page application 简称为 SPA) 是一种特殊的 Web 应用。它将全部的活动局限于一个Web页面中,仅在该Web页面初始化时加载相应的HTML、JavaScript 和 CSS。一旦页面加载完成了,SPA不会由于用户的操做而进行页面的从新加载或跳转。而是利用 JavaScript 动态的变换HTML的内(采用的是div切换显示和隐藏),从而实现UI与用户的交互。因为避免了页面的从新加载,SPA 能够提供较为流畅的用户体验。得益于ajax,咱们能够实现无跳转刷新,又多亏了浏览器的histroy机制,咱们用hash的变化从而能够实现推进界面变化.
为了单页面应用的要求(改变视图的同时不会向后端发出请求。),浏览器当前提供了如下两种支持hash和history:
hash —— 即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。
好比这个 URL:http://www.abc.com/#/hello,hash 的值为 #/hello。它的特色在于:hash 虽然出如今 URL 中,但不会被包括在 HTTP 请求中,对后端彻底没有影响,所以改变 hash 不会从新加载页面。
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(须要特定浏览器支持)
这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会当即向后端发送请求。
若是不想要很丑的 hash,咱们能够用路由的 history 模式,这种模式充分利用 history.pushState API 来完成
URL 跳转而无须从新加载页面。—— Vue-router 官网。
router去掉#
ui.router原理是改变location.hash的值,而location.hash 原本就是指 URL 里 # 符号及其后的部分,若是你是要作路由映射而且不想用基于 hash 的方案,那你应该考虑 HTML5 的 History API
$location服务支持配置两种URL格式:Hashbang模式(默认)和HTML5模式。两种模式下的API都是通用的。
静态网站,咱们须要修改的地方包含三个文件
index.html : ng-app的定义文件
app.js : 对应ng-app的控制文件
nginx.conf : nginx的网站配置文件
编辑 index.html,增长base标签。
在head标签里增长一行
<base href="/工程名/"> 编辑app.js,增长 $locationProvider.html5Mode(true) book.config(['$routeProvider', '$locationProvider', '$sceProvider', 'tplProvider', function ($routeProvider, $locationProvider, $sceProvider, tplProvider) { $routeProvider .when('/', {templateUrl: tplProvider.html('welcome'), controller: 'WelcomeCtrl'}) .when('/book', {templateUrl: tplProvider.html('book'), controller: 'BookCtrl'}) //图书 .when('/book-r1', {templateUrl: tplProvider.html('book-r1'), controller: 'BookR1Ctrl'}) //R的极客理想 .when('/video', {templateUrl: tplProvider.html('video'), controller: 'VideoCtrl'}) //视频 .when('/about', {templateUrl: tplProvider.html('about'), controller: 'AboutCtrl'}) //关于做者 .otherwise({redirectTo: '/'}); $locationProvider.html5Mode(true); }]);
编辑nginx的配置文件,增长try_files配置。
server { set $htdocs /www/deploy/mysite/onbook; listen 80; server_name onbook.me; location / { root $htdocs; try_files $uri $uri/ /工程名/index.html =404; } }
七.参考文献
AngularJs ng-route路由详解
深究AngularJS——ui-router详解
AngularJS中ngRouter和uiRouter的区别
多样化视图与嵌套视图
八.更多讨论
hash和history的好处是什么?
一、#! #很难看,不美观
二、微信支付接口,使用hash的话能够忽略#后的内容,只需定义主页的支付
三、seo优化,url#后的内容不会被收录
什么是路由?什么是NG路由?
简单来讲,路由就是给指定的页面分配一个url地址。经过这个url地址,你就能访问到该页面了。
好比你写了一个页面,/static/public/game/index.html,你的服务器项目域名http:www.dsxxx.com你经过一些方式,给该页面配置了一个路由地址/game那么,你就能够经过http:www.dsxxx.com/game访问到...,都是经过一些方式作了配置的,具体的方式你能够随着学习的深刻逐步了解到
NG路由天然是angularjs中使用的路由,天然也有vue-router,React-router等等
在路由中定义controller有什么意义,和直接在js里定义controller的区别是什么?
在angularjs中controller有三种写法
第一种
<pre name="code" class="javascript">var AppController = ['$scope', function($scope){ $scope.notifyServiceOnChage = function(){ console.log($scope.windowHeight); }; }]; app.controller('AppController',AppController);
在定义AppController的时候,先声明方法须要注入的参数,而后再定义方法体。最后将AppController绑定到app上。
第二种
app.controller('AppController', function($scope){ $scope.notifyServiceOnChage = function(){ console.log($scope.windowHeight); }; })
直接在app的controller属性定义,首先是controller名字,而后是方法体。
第三种
function AppController($scope) { $scope.notifyServiceOnChage = function(){ console.log($scope.windowHeight); }; }
直接写方法,而后在ng-controller引用该方法。