首页 >> 大全

17 多重视图和路由

2023-09-04 大全 22 作者:考证青年

多重视图和路由 相关概念理解

路由的作用,简单的概括就是基于View和Url的对应关系,处理跳转页面。

路由允许我们通过不同的 URL 访问不同的内容。

通过 可以实现多视图的单页Web应用( page web ,SPA)。

通常我们的URL形式为 ,但在单页Web应用中 通过 # + 标记 实现,例如:

http://runoob.com/#/first
http://runoob.com/#/second
http://runoob.com/#/third

当我们点击以上的任意一个链接时,向服务端请的地址都是一样的 ()。 因为 # 号之后的内容在向服务端请求时会被浏览器忽略掉。 所以我们就需要在客户端实现 # 号后面内容的功能实现。

路由 就通过 # + 标记 帮助我们区分不同的逻辑页面并将不同的页面绑定到对应的控制器上。

这里写图片描述

在以上图形中,我们可以看到创建了两个 URL: /first 和 /。每个 URL 都有对应的视图和控制器。

路由

即是的路由模块。在使用的时候,实际上,我们是在应用的主模块中引入模块并添加$服务到主模块的方法中来达到我们的目标。

$用于在主应用主模块的配置方法中。$route与$一般常见于控制器中。

使用 使用Bower安装

bower -route@X.Y.Z

在HTML中引入

<script src="angular.js" >script>
<script src="angular-route.js" >script>

在应用主模块中,引入

myApp = .('app', ['']);

4. 在模块的中绑定URL路径与控制器

config(['$routeProvider', function($routeProvider) {
// 在这里定义路由
}]);

模块组件详解

指令,提供不同路由模板插入的视图层。它会创建自己的作用域并将模板嵌套在内部。ng-view是一个优先级为1000的终极指令。指令遵循以下规则:

$

提供路由配置。有以下两个成员函数:

$routeProvider.when(url, {
template: string,
templateUrl: string,
controller: string, functionarray,
controllerAs: string,
redirectTo: string, function,
resolve: object<key, function>
});

路由映射信息route包含的选项:

resolve: {
'data': ['$http', function($http) {
return $http.get('/api').then(
function success(resp) { return response.data; },
function error(reason) { return false; }
);
}];
}

在上面的例子中,会发送一个$http请求,并将data的值替换为返回结果的值。列表中的键data会被注入到控制器中,所以在控制器中可以使用它。

path路径配置:

例如,形如/color/:color//:*\/edit的路由,将会匹配/color/brown//code/with//edit,并提取出:

$route

用于构建各个路由的url、view、这三者的关系。

方法:

事件:

* $

URL路由开始变化(未跳转成功)的时候触发的事件。

参数类型描述

event

合成的事件对象。

next

Route

将跳转的route信息。

Route

当前route信息。

* $

URL路由变化成功的时候触发的事件。

参数类型描述

event

合成的事件对象。

Route

当前route信息。

Route

上一个route信息。

* $

URL路由变化失败的时候触发的事件。

参数类型描述

event

合成的事件对象。

Route

当前route信息。

Route

上一个route信息。

Route

拒绝承诺,通常是失败承诺的错误。

* $$

当承诺被拒绝时广播。

参数类型描述

event

合成的事件对象。

Route

当前route信息。

$

解析返回路由中带有的参数。

如果我们设置下面这样的路由:

$routeProvider
.when('/inbox/:name', {
controller: 'InboxController',
templateUrl: 'views/inbox.html'
});

会在$中添加一个名为name的键,它的值会被设置为加载进来的URL中的值。

如果浏览器加载/inbox/all这个URL,那么$对象看起来会是下面这样:

{ name: 'all' }

需要注意,如果想要在控制器中访问这些变量,需要把$注入进控制器:

app.controller('InboxController', function($scope,$routeParams) {
// 在这里访问$routeParams
});

使用代码

<div ng-app="Demo" ng-controller="testCtrl as ctrl">
<a href="#/index/page1">page1a> - <a href="#/index/page2">page2a> - <a href="javascript:void(0)" ng-click="ctrl.reload()">reloada> - <a href="lavascript:void(0)" ng-click="ctrl.update()">updatea>
<div ng-view>div>
<script type="text/ng-template" id="page1.tpl">
this is page1.{{fisrtCtrl.value}}
script>
<script type="text/ng-template" id="page2.tpl">
this is page2.{{secondCtrl.value}}
script>
div>

(function () {
angular.module("Demo", ["ngRoute"])
.config(["$routeProvider",routeConfig])
.controller("testCtrl", ["$route","$scope",testCtrl])
.controller("firstPageCtrl",firstPageCtrl)
.controller("secondPageCtrl",secondPageCtrl);
function routeConfig($routeProvider){
$routeProvider.otherwise("/index/page1");
$routeProvider
.when("/index/page1",{
templateUrl:"page1.tpl",
controller:"firstPageCtrl",
controllerAs:"fisrtCtrl"
})
.when("/index/page2",{
templateUrl:"page2.tpl",
controller:"secondPageCtrl",
controllerAs:"secondCtrl"
});
};
function testCtrl($route,$scope) {
this.reload = function(){
$route.reload();
};
this.update = function(){
$route.updateParams({name:"beast"});
};
$scope.$on("$routeChangeStart",function(event,nextRoute,currentRoute){
//event.preventDefault(); //可控制不跳转页面,主要在路由权限控制的时候用的多
console.log(nextRoute,currentRoute);// 下一个路由信息和上一个路由信息
});
};
function firstPageCtrl(){
this.value = "hello world";
console.log("this is page1");//用于证明reload
}
function secondPageCtrl(){
this.value = "Hello World";
console.log("this is page2");//用于证明reload
}
}());

这里直接使用了ng-把两个模板写在一个页面,在实际使用中,可以把两个模板分开分别放到两个不同的html文件中,并且放到一个规定的文件中,这样可方便于管理。

$详解

$服务:

在URL改变时,不要刷新整个页面。一定要的话,用低级的API$..href。

$方法

$服务为URL只读部分(, , host, port)提供读方法,为可读写部分(url, path, , hash)提供读写方法。

方法描述

()

获取完整的url路径

();

获取协议

host();

获取主机名

port();

获取主机端口

url([url], []);

获取当前url的#后面的内容,包括参数和哈希值

path([path]);

获取当前url的子路径(也就是当前url#后面的内容,不包括参数)。

(,[]);

获取参数的json对象

hash([hash]);

获取url的哈希值

();

替换上一次浏览记录。如果被调用,当前$过程中所有$的变化将取代当前的历史记录,而不是增加新的历史记录。

state([state]);

返回当前url的历史状态对象(不包括任何参数)。调用一个参数并且返回$时改变历史状态对象。

所有的写方法返回同一个$对象来支持链式风格。比如,要在一条语句中改变URL的多个部分:

$.path('/').({key: value});

_路由跟踪图_管道路由图

// 假定原来的完整url为:
// http://localhost:63342/test/templates/demo01.html#/tabs/chat?name=JK&age=10#noHash
var url = $location.url("url2").absUrl();
// 到这里变成:
// http://localhost:63342/test/templates/demo01.html#/url2
url = $location.path("path2")
.search({
name: "CL",
age: 12
})
.hash('hash2')
.absUrl();
// 到这里变成:
// http://localhost:63342/test/templates/demo01.html#/path2?name=CL&age=12#hash2

$事件

参数类型描述

合成事件对象。

新的url。

改变前的url。

新的历史状态对象。

改变前的历史状态对象。

使用代码

(function(){
angular.module('Demo', [])
.controller('testCtrl',["$location","$scope",testCtrl]);
function testCtrl($location,$scope) {
var url = "http://example.com:8080/#/some/path?foo=bar&baz=xoxo#hashValue";
$location.absUrl();// http://example.com:8080/#/some/path?foo=bar&baz=xoxo#hashValue
$location.url();// some/path?foo=bar&baz=xoxo
$location.protocol();// http
$location.host();// example.com
$location.port();// 8080
$location.path();// /some/path
$location.search();// {foo: 'bar', baz: 'xoxo'}
$location.search('foo', 'yipee');
$location.search();// {foo: 'yipee', baz: 'xoxo'}
$location.hash();// #hashValue
$scope.$on("$locationChangeStart", function () {
//监听url变化,在变化前做想要的处理
});
$scope.$on("$locationChangeSuccess", function () {
//监听url变化,在变化后做想要的处理
});
}
}());

$在日常开发中是很有用的,特别是$和$s,在做是否登录判断的时候配合拦截器使用,根据拦截器返回的状态,监听url变化并在需要登录的时候退出到登录页面。

()方法

$服务有一个特殊的方法可以用来告诉$服务下一次自动和浏览器同步,上一条浏览记录应该被替换而不是创建一个新的。这在重定向的时候很好用。不这样的话容易使后退按钮失效(点后退时会又触发重定向)。要改变URL而不添加新的历史记录,你可以这样做:

$.path('/').();

注意写方法并不会马上更新.,而是在作用域的$阶段将多个$操作合并成一个对.对象的操作。因为多个操作会后对浏览器来说都会只是一个,所以只要调用一次()方法就能实现浏览器记录的替换操作。一旦浏览器更新了,$ 服务就会将方法的标志重置,以后的改变就会创建新的历史记录,直到再次调用方法。

$服务配置

要想配置$服务,应该获取$对象,然后按下面的方法设置它的参数:

范例配置

$.(true).('!');

$.path()与!或/前缀

Path永远会以正斜杠(/)开头,$.path()作为方法调用时,如果没有用正斜杠开头,它会给加上一个。

注意,在模式中,!前缀并不是$.path()的一部分;它只是hash“前缀”。

写方法和字符编码

你可以给$服务传递特殊字符,它会根据 RFC 3986 规则来编码。当你调用写方法时:

$的双向绑定

因为 $ 使用/, 你可以使用 ng-model-="{ : true }"来将它绑定到 .

<div ng-controller="LocationController">
<input type="text" ng-model="locationPath" ng-model-options="{ getterSetter: true }" />
div>

angular.module('locationExample', [])
.controller('LocationController', ['$scope', '$location', function($scope, $location) {
$scope.locationPath = function(newLocation) {
return $location.path(newLocation);
};
}]);

和HTML5模式

$服务有两种配置模式,它将控制浏览器地址栏中的地址显示格式:模式(默认)和HTML5模式, 后者基于HTML5的历史()API。无论哪种模式,应用层都使用相同的API, $服务会自己找出合适的URL格式和浏览器API,来完成修改浏览器地址和进行历史管理的工作。

模式HTML5模式

配置项

默认

URL格式

在所有浏览器中使用格式

link重写

需要服务端配置

模式(缺省模式)

在这种模式中,$在所有浏览器中都使用地址.

it('显示范例', inject(
function($locationProvider) {
$locationProvider.html5Mode(false);
$locationProvider.hashPrefix('!');
},
function($location) {
// 打开http://example.com/base/index.html#!/a
$location.absUrl() == 'http://example.com/base/index.html#!/a'
$location.path() == '/a'
$location.path('/foo')
$location.absUrl() == 'http://example.com/base/index.html#!/foo'
$location.search() == {}
$location.search({a: 'b', c: true});
$location.absUrl() == 'http://example.com/base/index.html#!/foo?a=b&c'
$location.path('/new').search('x=y');
$location.absUrl() == 'http://example.com/base/index.html#!/new?x=y'
}
));

HTML5模式

在HTML5模式中,$服务的和方法通过HTML5 API与浏览器地址栏互动, 它允许你使用标准的URL path和格式来代替等价的模式。如果浏览器不支持HTML5 API, 那么$服务将自动退回到使用 URL。这将把你从担心用户的浏览器是否支持 API中解放出来, $服务将会透明的帮你选择最佳的可用形式。

it('显示范例', inject(
function($locationProvider) {
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
},
function($location) {
// 在支持HTML5历史API的浏览器中:
// 打开 http://example.com/#!/a -> 将被重写为 http://example.com/a
// (替换 http://example.com/#!/a 的历史记录)
$location.path() == '/a'
$location.path('/foo');
$location.absUrl() == 'http://example.com/foo'
$location.search() == {}
$location.search({a: 'b', c: true});
$location.absUrl() == 'http://example.com/foo?a=b&c'
$location.path('/new').search('x=y');
$location.url() == 'new?x=y'
$location.absUrl() == 'http://example.com/new?x=y'
// 在不支持HTML5历史API的浏览器中:
// 打开 http://example.com/new?x=y -> 将被重定向到 http://example.com/#!/new?x=y
// (替换 http://example.com/new?x=y 的历史记录)
$location.path() == '/new'
$location.search() == {x: 'y'}
$location.path('/foo/bar');
$location.path() == '/foo/bar'
$location.url() == '/foo/bar?x=y'
$location.absUrl() == 'http://example.com/#!/foo/bar?x=y'
}
));

$.hash([hash])和$

$的hash方法填入一个DOM元素的id值,可以快速定位到该DOM元素。

在普通的html网页中,我们可以通过在url后边添加 # 的方式,将页面显示定位到某个元素,也就是锚点。

但是在应用的网页中,页面路由的写法是 #route/route。锚点的写法会被当做一个页面路由解析过去,达不到定位的目的。

提供一个$服务用来做锚点的功能。$监听$.hash()并且滚动到url指定的锚点的地方。可以通过$.()禁用。

<div id="scrollArea" ng-controller="ScrollController">
<a ng-click="gotoBottom()">Go to bottoma>
<a id="bottom">a> You're at the bottom!
div>

angular.module('anchorScrollExample', [])
.controller('ScrollController', ['$scope', '$location', '$anchorScroll',
function ($scope, $location, $anchorScroll) {
$scope.gotoBottom = function() {
// set the location.hash to the id of
// the element you wish to scroll to.
$location.hash('bottom');
// call $anchorScroll()
$anchorScroll();
};
}]);

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了