angularjs默认提供的路由是angular-route.min.js提供的,这里介绍一个开源的,基于angularjs实现的ui-router路由。思路是类似的。页面不再使用ng-view来指定一个模板子页面,而是通过<ui-view></ui-view>指定一个模板子页面,同样也是预留出来,当有需要的时候,页面自动套用。
这里演示一个简单的路由,首先模拟从登陆页面,跳转到主页面,然后主页面可以切换到用户列表。效果图如下:
这里使用的angularjs版本是1.6.9,页面需要引入angular.min.js,angular-ui-router.min.js,另外,还需要一些页面相关的js。
index.html
<!doctype html>
<html ng-app="nodejs">
<head>
<meta charset="UTF-8"/>
<title>nodejs</title>
<link rel="stylesheet" type="text/css" href="/css/reset.css"/>
<link rel="stylesheet" type="text/css" href="/css/public.css"/>
</head>
<body>
<div id="container">
<ui-view></ui-view>
</div>
<script type="text/javascript" src="/js/libs/angular.min.js"></script>
<script type="text/javascript" src="/js/libs/angular-ui-router.min.js"></script>
<script type="text/javascript" src="/js/common.js"></script>
<script type="text/javascript" src="/js/admin.js"></script>
<script type="text/javascript" src="/js/user.js"></script>
<script type="text/javascript">
var app = angular.module("nodejs",["ui.router","common","admin","user"]);
app.config(function($stateProvider,$locationProvider,$httpProvider){
var baseState = {
abstract:true,
name:'baseState',
templateUrl:'views/common/base.html',
controller:'rootController'
};
var loginBaseState = {
abstract:true,
name:'loginBaseState',
templateUrl:'views/common/login-base.html'
};
var states = [
baseState,
loginBaseState,
{
parent:loginBaseState,
name:'login',
templateUrl:'views/user/login.html',
url:"",
controller:'userController'
},
{
parent:baseState,
name:'main',
templateUrl:'views/admin/main.html',
url:"/admin/main",
controller:'mainController'
},
{
parent:baseState,
name:'user',
templateUrl:'views/user/list.html',
url:"/user/list",
controller:'userController'
}
];
angular.forEach(states,function(state){
$stateProvider.state(state.name,state);
});
$locationProvider.hashPrefix("");
});
</script>
</body>
</html>
views/common/base.html
<header>this is page header</header>
<main>
<aside>
<h2>menu</h2>
<ul>
<li><a href="#/admin/main">主界面</a></li>
<li><a href="#/user/list">用户管理</a></li>
</ul>
</aside>
<section>
<ui-view></ui-view>
</section>
</main>
<footer>this is page footer</footer>
views/common/login-base.html
<header>this is page header</header>
<main>
<section>
<h2>login page</h2>
<ui-view></ui-view>
</section>
</main>
<footer>this is page footer</footer>
views/admin/main.html
<div>主界面</div>
views/user/list.html
<div>
<h2>用户列表页面</h2>
<ul ng-repeat="user in list">
<li>ID:{{user.id}}-Name:{{user.name}}</li>
</ul>
</div>
views/user/login.html
<div>
<form>
<div>
<label>用户名:</label>
<input type="text" name="username"/>
</div>
<div>
<label>密码:</label>
<input type="password" name="password"/>
</div>
<div>
<input type="button" value="登录" ng-click="login()"/>
</div>
</form>
</div>
js/common.js
var commonModel = angular.module("common",[]);
commonModel.controller("rootController",function($scope){
});
js/admin.js
var adminModel = angular.module("admin",[]);
adminModel.controller("mainController",function($scope){
});
js/user.js
var userModel = angular.module("user",[]);
userModel.controller("userController",function($scope,$location){
$scope.list = [
{id:101,name:'angularjs'},
{id:102,name:'nodejs'}
];
$scope.login = function(){
//alert("login");
$location.path("/admin/main");
}
});
css/reset.css
*{margin:0;padding:0;}
html,body,input,a,p,h1,h2,h3,h4,h5,h6{font-size: 100%;font-weight: normal;font-family: Helvetica;}
a{text-decoration: none;color: #0088cc;}
.clearfix{*zoom:1;}
.clearfix:before,.clearfix:after{
display: table;
line-height: 0;
content:'';
}
.clearfix:after{
clear: both;
}
.fl{float:left;}
.fr{float:right;}
ul{list-style: none;}
css/public.css
html,body{height: 100%;}
#container{min-height: 100%;position: relative;}
main{display:flex;}
aside{flex:left;background:#ccc;}
section{flex:1;}
所需要的资源就罗列完成了,需要的angularjs文件这里没有列出来,可以直接去官网或者github下载。
这里因为用到了angular的路由,所以,项目启动必须使用一个http服务,不能直接通过浏览器打开index.html访问。我们在index.html页面中配置了如下的state:
{
parent:loginBaseState,
name:'login',
templateUrl:'views/user/login.html',
url:"",
controller:'userController'
}
其中url配置的是"",相当于访问首页,就是登录页面,这里虽然首页是index.html没错,但是它只是一个容器,没有内容,具体的内容还需要url=""的页面来填充。这里我们定义了两个base页面,一个是baseState,另一个是loginBaseState,他们都是abstract,即抽象的,他可以被继承,继承的页面只需要指定parent即可,这样,可以通过base页面来生成一些页面框架,而不用每个页面都单独编写。如用户管理页和主页面,都有页头,页尾,还有左侧菜单栏。当我们继承了base页面之后,用户管理页面和主页面的内容就剩下自己的部分,可以说很简单了。
angularjs路由,会把页面都分成小小的片段,不同的路由对应不同的页面主体,每个片段不必是一个完整的html文件。这一点会让我们疑惑。
angularjs1.6版本默认的路由 ,在路径上,会有一个bug,就是url中的"/"会被转义成为%2F,这样,当我们在浏览器上输入/user/list,会变成%2Fuser%2Flist,这样,我们的请求就到不了真正的页面。
这个问题的解决办法就是加入如下代码到路由控制部分。
$locationProvider.hashPrefix("");
这样路由url转义的问题就解决了,上面的示例代码index.html中就已经使用了该代码,所以开始的演示中,没有出现url转义导致的问题。