angular--路由
ng-view是由ngRoute模块提供的一个特殊指令,它的独特作用是在HTML中给$route对应的
视图内容占位。
它会创建自己的作用域并将模板嵌套在内部。
mg-view是一个优先级为1000的终极指令。AngularJS不会运行同一个元素上的
低优先级指令(例如<div ng-view></div>元素上其他指令都是没有意义的)。
ngView指令遵循以下规则。
每次触发$routeChangeSuccess事件,视图都会更新。
如果某个模板同当前的路由相关联:
创建一个新的作用域;
移除上一个视图,同时上一个作用域也会被清除;
将新的作用域同当前模板关联在一起;
如果路由中有相关的定义,那么就把对应的控制器同当前作用域关联起来;
触发$viewContentLoaded事件;
如果提供了onload属性,调用该属性所指定的函数。
路由
我们可以使用AngularJS提供的when和otherwise两个方法来定义应用的路由。
用config函数在特定的模块或应用中定义路由。
angular.module('myApp', []).
config(['$routeProvider', function($routeProvider) {
// 在这里定义路由
}]);
这里我们用了数组这种特殊的依赖注入语法。现在,我们可以用when方法来添加一个特定的路由。这个方法可以接受两个参数(when(path,route))。
下面的例子展示了如何创建一个独立的路由:
angular.module('myApp', []). config(['$routeProvider', function($routeProvider) { $routeProvider .when('/', { templateUrl: 'views/home.html', controller: 'HomeController' }); }]);
第一个参数是路由路径,这个路径会与$location.path进行匹配,$location.path也就是
当前URL的路径。如果路径后面还有其他内容,或使用了双斜线也可以正常匹配。我们可以在
URL中存储参数,参数需要以冒号开头(例如:name),后面会讨论如何用$routeParams读取这
些参数。
第二个参数是配置对象,决定了当第一个参数中的路由能够匹配时具体做些什么。配置对象
中可以进行设置的属性包括controller、template、templateURL、resolve、redirectTo和
reloadOnSearch。
一个复杂的路由方案会包含多个路由,以及一个可以将所有意外路径进行重定向的捕获器。
angular.module('myApp', []). config(['$routeProvider', function($routeProvider) { $routeProvider .when('/', { templateUrl: 'views/home.html', controller: 'HomeController' }) .when('/login', { templateUrl: 'views/login.html', controller: 'LoginController' }) .when('/dashboard', { templateUrl: 'views/dashboard.html', controller: 'DashboardController', resolve: { user: function(SessionService) { return SessionService.getCurrentUser(); } } }) .otherwise({ redirectTo: '/' }); }]);
1. controller
controller: 'MyController'
// 或者
controller: function($scope) {}
如果配置对象中设置了controller属性,那么这个指定的控制器会与路由所创建的新作用
域关联在一起。如果参数值是字符型,会在模块中所有注册过的控制器中查找对应的内容,然后
与路由关联在一起。如果参数值是函数型,这个函数会作为模板中DOM元素的控制器并与模板
进行关联。
2. template
template: '<div><h2>Route</h2></div>'
AngularJS会将配置对象中的HTML模板渲染到对应的具有ng-view指令的DOM元素中。
3. templateUrl
templateUrl: 'views/template_name.html'
应用会根据templateUrl属性所指定的路径通过XHR读取视图(或者从$templateCache中读
取)。如果能够找到并读取这个模板,AngularJS会将模板的内容渲染到具有ng-view指令的DOM
元素中。
4. resolve
resolve: { 'data': ['$http', function($http) { return $http.get('/api').then( function success(resp) { return response.data; }, function error(reason) { return false; } ); }]; }
如果设置了resolve属性,AngularJS会将列表中的元素都注入到控制器中。如果这些依赖是
promise对象,它们在控制器加载以及$routeChangeSuccess被触发之前,会被resolve并设置成一
个值。
列表对象可以是:
键,键值是会被注入到控制器中的依赖的名字;
工厂,即可以是一个服务的名字,也可以是一个返回值,它是会被注入到控制器中的函
数或可以被resolve的promise对象。
在上面的例子中,resolve会发送一个$http请求,并将data的值替换为返回结果的值。列
表中的键data会被注入到控制器中,所以在控制器中可以使用它。
5. redirectTo
redirectTo: '/home'
// 或者
redirectTo: function(route,path,search)
如果redirectTo属性的值是一个字符串,那么路径会被替换成这个值,并根据这个目标路
径触发路由变化。
如果redirectTo属性的值是一个函数,那么路径会被替换成函数的返回值,并根据这个目
标路径触发路由变化。
如果redirectTo属性的值是一个函数,AngularJS会在调用它时传入下面三个参数中:
(1) 从当前路径中提取出的路由参数;
(2) 当前路径;
(3) 当前URL中的查询串。
6. reloadOnSearch
如果reloadOnSearch选项被设置为true(默认),当$location.search()发生变化时会重新
加载路由。如果设置为false,那么当URL中的查询串部分发生变化时就不会重新加载路由。这
个小窍门对路由嵌套和原地分页等需求非常有用。
现在介绍用when函数来设置路由。
下面的例子中设置了两个路由:一个首页路由和一个收件箱路由,同时首页路由被设置成默
认路由。
angular.module('MyApp', []). config(['$routeProvider', function($routeProvider) { $routeProvider .when('/', { controller: 'HomeController', templateUrl: 'views/home.html' }) .when('/inbox/:name', { controller: 'InboxController', templateUrl: 'views/inbox.html' }) .otherwise({redirectTo: '/'}); }]);
如上,我们已经用when方法设置了两个路由。otherwise方法会在没有任何路由匹配时被调
用,我们用它设置了一个默认跳转到'/'路径的路由。
当浏览器加载AngularJS应用时,会将URL设置成默认路由所指向的路径。除非我们在浏览
器中加载不同的URL,否则默认会使用/路由。
$routeParams
前面提到如果我们在路由参数的前面加上:,AngularJS就会把它解析出来并传递给$routeParams。
例如,如果我们设置下面这样的路由:
$routeProvider .when('/inbox/:name', { controller: 'InboxController', templateUrl: 'views/inbox.html' });
AngularJS会在$routeParams中添加一个名为name的键,它的值会被设置为加载进来的URL
中的值。
如果浏览器加载/inbox/all这个URL,那么$routeParams对象看起来会是下面这样:
{ name: 'all' }
需要注意,如果想要在控制器中访问这些变量,需要把$routeParams注入进控制器:
app.controller('InboxController', function($scope,$routeParams) { // 在这里访问$routeParams });
$location 服务
AngularJS提供了一个服务用以解析地址栏中的URL,并让你可以访问应用当前路径所对应
的路由。它同样提供了修改路径和处理各种形式导航的能力。
$location服务对JavaScript中的window.location对象的API进行了更优雅地封装,
并且和AngularJS集成在一起。
当应用需要在内部进行跳转时是使用$location服务的最佳场景,比如当用户注册后、修改
或者登录后进行的跳转。
$location服务没有刷新整个页面的能力。如果需要刷新整个页面,需要使用$window.
location对象(window.location的一个接口)。
1. path()
path()用来获取页面当前的路径:
$location.path(); // 返回当前路径
修改当前路径并跳转到应用中的另一个URL:
$location.path('/'); // 把路径修改为'/'路由
path()方法直接和HTML5的历史API进行交互,所以用户可通过点击后退按钮退回到上一个
页面。
2. replace()
如果你希望跳转后用户不能点击后退按钮(对于登录之后的跳转这种发生在某个跳转之后的
再次跳转很有用),AngularJS提供了replace()方法来实现这个功能:
$location.path('/home'); $location.replace(); // 或者 $location.path('/home').replace();
3. absUrl()
absUrl()方法用来获取编码后的完整URL:
$location.absUrl()
4. hash()
hash()方法用来获取URL中的hash片段:
$location.hash(); // 返回当前的hash片段
5. host()
host()方法用来获取URL中的主机:
$location.host();// 当前URL的主机
6. port()
port()方法用来获取URL中的端口号:
$location.port();// 当前URL的端口
7. protocol()
protocol()方法用来获取URL中的协议:
$location.protocol();// 当前URL的协议
8. search()
search()方法用来获取URL中的查询串:
$location.search();
我们可以向这个方法中传入新的查询参数,来修改URL中的查询串部分:
// 用对象设置查询
$location.search({name: 'Ari', username: 'auser'});
// 用字符串设置查询
$location.search('name=Ari&username=auser');
search方法可以接受两个参数。
search(可选,字符串或对象)
这个参数代表新的查询参数。hash对象的值可以是数组。
paramValue(可选,字符串)
如果search参数的类型是字符串,那么paramValue会做为该参数的值覆盖URL当中的对应
值。如果paramValue的值是null,对应的参数会被移除掉。
9. url()
url()方法用来获取当前页面的URL:
$location.url(); // 该URL的字符串
如果调用url()方法时传了参数,会设置并修改当前的URL,这会同时修改URL中的路径、
查询串和hash,并返回$location。
// 设置新的URL
$location.url('/home?name=Ari#hashthing');
url()方法可以接受两个参数。
url(可选,字符串)
新的URL的基础的前缀。
replace(可选,字符串)
想要修改成的路径。