- 浏览: 501115 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (241)
- Jscript笔记 (23)
- sql (8)
- jQuery (23)
- css (2)
- jQuery.form (2)
- struts2 (3)
- 数据库字符集 (3)
- Java (15)
- Oracle (2)
- DB2 (4)
- ResourceBundle (1)
- Exception (7)
- Windows (2)
- 数据库 (18)
- JSP (2)
- jstree (3)
- datatable (9)
- bootstrap-switch (1)
- select2 (3)
- Java.tree (1)
- JSF2 (1)
- Bootstrap (1)
- Eclipse (13)
- SVN (3)
- Eclipse插件 (5)
- myeclipse (1)
- ajax (1)
- JBOSS (2)
- data storage (1)
- Apache tiles (1)
- springMVC (15)
- mybatis (6)
- AngularJS (13)
- checkbox (1)
- J2EE (1)
- SecureCRT (7)
- tomcat (4)
- Maven (3)
- log4j (3)
- Xshell (1)
- 工具应用 (5)
- spring (12)
- Apache (5)
- books (1)
- fastjson (1)
- Standard (1)
- Mysql (1)
- MAC (1)
- Charles (1)
- LINUX (1)
- 日常开发ISSUE (0)
最新评论
-
yuchangcheng:
直接把代码 上传上来吧 这样看的很吃力呀
mybatis generator 的复合查询 -
zzd0058:
我表示报400错误
SpringMVC接收复杂集合参数 -
lihaiming:
影非弦 写道没有这个页面详细的文件么?文档地址:https:/ ...
select2.js使用 -
影非弦:
没有这个页面详细的文件么?
select2.js使用 -
影非弦:
这个select.min.css是select2提供的样式文件 ...
select2.js使用
AngularJS自带有路由模块ngRoute,但是有经验的老师都推荐我们使用功能更完善更强大的ui-router来做路由。那到底什么是路由呢?我自己的理解是:路由可以看作一个总控制器,它会根据页面的不同状态来填充页面的内容,这就是路由的主要用处。前端路由能极大地减少对服务器资源的请求数量,因此在前端做路由显得尤为重要。
-----------------------------------------------------------------
由于路由是控制整个应用的显示状态的,所以我们要让路由模块第一时间接管整个应用。
使用ui-router很简单,下载它的包,在index.html中引入js文件,然后在模块的依赖中引入即可。
1
var routerApp = angular.module('routerApp', ['ui.router']);
ui-router的本质其实是向我们预留的部分填充模板,它会在页面中去寻找ui-view这条指令,然后根据当前页面状态把对应的模板填充到ui-view所在的区块中。
比如一个典型的页面是nav+footer固定不变,中间主要部分作为内容显示区域时常发生变化。对应的页面结构就是
1
2
3
4
5
<body>
<nav>This is nav</nav>
<div ui-view></div>
<footer>This is footer</footer>
</body>
然后我们的路由根据页面的状态,选择不同的html模板填充到ui-view的这个div里面。
在js中具体怎么使用ui-router呢
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
routerApp.config(function($stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise('/index');
$stateProvider
.state('index',{
url : '/index',
templateUrl : 'tpls/index.html'
})
.state('list',{
url : '/list',
templateUrl : 'tpls/list.html'
})
.state('detail',{
url : '/detail',
templateUrl : 'tpls/detail.html'
});
});
以上就是angular路由最基本的模板。但是要注意一个问题,state的第一个参数并不是匹配规则,而是叫状态名,也就是说这个参数事实上可以是任意的,它用来给当前状态增加一个名字,触发路由规则还是看url的内容。比如这样
1
2
3
4
.state('home',{
url : '/index',
templateUrl : 'tpls/index.html'
})
我们必须要地址栏输入www.xx.com/index,才会加载对应的模板而不是输入home,它仅仅是一个名字而已。
但是说,这个名字也是有它的作用的。看一个例子就明白了。
index.html
1
2
3
<nav>This is the nav</nav>
<div ui-view></div>
<footer>This is the footer</footer>
list.html
1
2
3
4
<div>
<p>this is the list page</p>
<div ui-view></div>
</div>
list-main.html
1
2
3
<div>
<p>This is list-main Page</p>
</div>
如果我们的路由这么写
1
2
3
4
5
6
7
8
.state('aaa',{
url : '/list',
templateUrl : 'tpls/list.html'
})
.state('bbb',{
url : '/list/main',
templateUrl : 'tpls/list-main.html'
})
那当我们在浏览器中输入www.xx.com/list/main的时候,页面结果为
5472d6ee0001fc2803350157.jpg
如果我们的路由这么写
1
2
3
4
5
6
7
8
.state('aaa',{
url : '/list',
templateUrl : 'tpls/list.html'
})
.state('aaa.bbb',{
url : '/main',
templateUrl : 'tpls/list-main.html'
})
那当我么输入www.xx.com/list/main的时候,页面结果为
5472d6fd0001ebcf03690177.jpg
也就是说state的的第一个参数为页面定义了一个名字,这个页面的模板只能放到它的父级中的ui-view去。如果没有.这种写法,那么默认的父级是index.html,所以第一种写法bbb模板的父级是index.html,所以输入/list/main时会把对应模板加载到index.html中的ui-view里面。而第二种写法aaa.bbb,这意思是说bbb的父级是aaa,所以bbb的模板要放到aaa模板(也就是list.html)中的ui-view中。这时的url是在aaa页面的url后的url。
当然还有页面的嵌套,这部分其实大漠老师在视频中已经讲得很清楚了。
这是路由需要注意的一个作用域问题。
-----------------------------------------------------------------------
当然路由还有很多其他问题,因为路由是angularjs中很重要的一部分,但基本的用法就是上面所讲的了,如果把所有静态页面都写好了,那么用以上的内容就已经能做出一个精美的web了。现在学习了路由的基本用法,其它问题的话我们碰到一个再解决一个吧。
2014-11-24AngularJSJavaScript9488 浏览15 回答
PHPBird
今天还是来说一下angular中的路由模块。我们实际项目中,各个页面的切换是经常会与Auth相关的。比如我网站的后台,是需要登录过的用户才能进去,那么我们用angularJS做前端路由的时候应该怎么完成这个功能呢
------------------------------------------------------------------------
我们还是先设想一个最简单的场景吧。我们的应用有两个页面,登录页面后内容页面,要求是必须要验证登录成功后才能进入内容页面,下面我们一起来实现一下这个例子吧。当然我觉得我的方法可能会比较Low,但是学习阶段我们能先把功能做出来比什么都重要。
首先用bootstrap来写一个简单的登录页面吧。具体bootstrap代码我就不说了,我们关注的是angular在这里面如何用起来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="col-md-offset-3 col-md-4">
<form class="form" role="form" name="loginForm" ng-submit="loginCheck()">
<div class="form-group">
<label class="control-label">用户名</label>
<input type="text" class="form-control" required placeholder="请输入管理员账号" ng-model="admin.username">
</div>
<div class="form-group">
<label class="control-label">密码</label>
<input type="password" class="form-control" ng-model="admin.pwd" required placeholder="请输入密码">
</div>
<div ng-show="showError" class="alert alert-danger alert-dismissible" role="alert">
<button ng-click="showError=false" type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">关闭</span></button>
用户名或密码错误!!你还有一次机会
</div>
<input type="submit" class="btn btn-primary btn-lg" value="登录" ng-disabled="loginForm.$invalid">
</form>
</div>
效果如下
54788faf000197b405000227.jpg
当然我之前还有一些css的布局,粘代码过去可能会出错哦,至少得在最外层加一个div class="row"
还可以看见,我给登录按钮加了个ng-disabled,当表单没有通过验证的时候是不能点登录的。
然后我加了一个提示的tips,用到了ng-show,在controller里会有一个showError的属性来控制它的显示,当验证账号密码错误时showError为true。
当我们验证出错的时候
547892c90001675104860298.jpg
接着我们来看一下路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var myApp = angular.module('myApp', ['ui.router','myModule']);
myApp.run(function($rootScope, $state, $stateParams){
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$rootScope.$state.isLogin = false;
});
myApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login',{
url : '/login',
templateUrl : 'tpls/login.html',
controller : 'LoginController'
})
.state('index',{
url : '/index',
templateUrl : 'tpls/index.html',
controllerProvider : function($rootScope){
if($rootScope.$state.isLogin == false){
$rootScope.$state.go('login');
}
return function(){};
}
});
}
因为在整个页面中我们都会用到登录状态,所以我把登录状态绑定到rootscope中,isLogin刚开始是false表示未登录。
接着看路由里面,login这个很简单,主要看index页面。
关键的一步就是index的controller,在这里我选择用controllerProvider的方式来生成controller,可以看到我们最后实际上是返回的一个空的function,但是在返回空controller之前(index页面还没有解析),我可以做一些事情,那就是验证权限啦!
如果$rootScope.$state.isLogin为false也就是还没有登录,那就直接跳转到登录页面。跳转用到了$state里面的go方法,go中的变量就是我们每个页面的状态名,也就是state的第一个参数。我是go('login'),它就跳转到state的第一个参数是login的那个页面去了,也就是登录页面。换句话说,如果我们登录提交后验证没有成功,当我们在地址栏输入/index的时候会跳到登录页面的哦。
那么再来看看我们的验证模块。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
myModule
.controller('LoginController', function($scope,$rootScope,$http){
$scope.showError = false;
$scope.loginCheck = function(){
var username = $scope.admin.username;
var pwd = $scope.admin.pwd;
var loginSuccess = false;
http.get('/acm-admin/data/user.json')
.success(function(response){
for(var i=0; i<response.length; i++){
if(response[i].username == username && response[i].pwd == pwd){
$rootScope.$state.isLogin = true;
loginSuccess = true;
$rootScope.$state.go('index');
}
}
if(!loginSuccess){
$scope.showError = true;
}
});
}
})
初始化我们给showError一个值为false,不要显示错误提示框。然后来看看验证登录的这个方法。首先获取到用户输入的用户名和密码,设置登录成功的状态的false。然后通过$http.get,到指定的地方去取一个json文件,很显然这是个假数据,我们把预设的用户名和密码存放到这个json文件中。取出预设的用户名和密码之后就和用户输入的来进行对比,相信这都很简单,大家肯定能看明白。如果用户名和密码都对上了,那么就把登录状态设置为true,登录成功也设置为true。然后用$state的go方法跳转到Index页面。
如果登录信息验证失败,那么就把showError赋为true,页面上就会显示提示信息咯。
----------------------------------------------------------------------------
怎么样,很简单吧。当然还有其它实现这一功能的方法,而且我上述的方法很可能还有诸多安全隐患,而且模块的分工也是不明确的,淡然实际部署不推荐这么写了。我们可以优化改进的地方很多,比如验证的模块是不是应该独立出去呢,或者用户有没有什么办法能轻易绕过这个登录保护呢?这就留待小伙伴们自己探究了……继续学习angular去了,大家晚安!!
2014-11-28 回复 2
PHPBird
其实路由的功能是比较复杂的,我们实际应用中页面的状态也是非常多的,上面简单的路由是肯定不能满足我们的需求的,所以我们必须要更深入地了解下路由以及它更有用的一些用法。
--------------------------------------------------------------------
首先来说一下templateUrl属性,上面说了它的值是对应模板的地址,比如
1
2
3
...
templateUrl : 'tpls/index.html',
...
但事实上我们也可以用一个函数作为值,但是这个函数必须返回模板的地址,比如
1
2
3
4
5
...
templateUrl : function(){
return 'tpls/index.html';
},
...
这两段代码的效果其实是一模一样的,很容易理解。但是我们在实际应用的时候会经常有这样的需求:在url里拼接get参数,然后后台利用get参数去读数据库然后返回相应的内容。这时候用第一种方法实现起来可能就不那么容易(但是也是能实现的),而用第二种方法就很容易了。
那么在这之前需要介绍一个很有用的东西叫做$stateParams,看名字也很容易理解,状态参量。这个东西就存储了页面状态的有关信息,我们通过一个例子来看看这到底是神马东东。
这是我们的list.html页面
1
2
3
4
5
<div>
<p>This is the list page</p>
<a ui-sref="detail({articleId:'111'})">文章详情</a>
</div>
这是detail.html页面
1
2
3
<div>
<p>This is the detail page</p>
</div>
这是路有部分了,注意看哟
1
2
3
4
5
6
7
8
9
10
11
.state('list',{
url : '/list',
templateUrl : 'tpls/list.html'
})
.state('detail',{
url : '/detail/{articleId}',
templateUrl : function($stateParams){
console.log($stateParams);
return 'tpls/detail.html';
}
})
先来看看效果,当我们进入list页面时是下面这个样子
5475f3190001e56403160176.jpg
我们点击文章详情这个链接后,页面变成了detail,并且下面打印出了$stateParams
5475f3190001aba903240258.jpg
这里我们发现它是一个对象,并且包含了我们所传递的参数。小伙伴们看看我上面是怎么在url里传递参数的哦,就是加一个括号,里面放一个我们要传递的对象即可。传递对象参数的时候需要注意,路由中url后面跟了多少参数你就只能传递那么多参数,比如
路由中这么写
1
2
3
4
5
6
7
.state('detail',{
url : '/detail/{articleId}/{else}',
templateUrl : function($stateParams){
console.log($stateParams);
return 'tpls/detail.html';
}
})
html页面中这么写
1
2
3
4
<div>
<p>This is the list page</p>
<a ui-sref="detail({articleId:'111',else:'imooc'})">文章详情</a>
</div>
那我们输出的效果就是这样的
5475f62c0001ec4303800275.jpg
怎么能用它呢?小伙伴们记得路由中的另一个参数controller,它为模板指定了一个controller,事实上我们可以把$stateParams传入controller中,看个例子吧
首先我们在index.html引入controller.js
list页面和上面没有变化
1
2
3
4
<div>
<p>This is the list page</p>
<a ui-sref="detail({articleId:'111',else:'imooc'})">文章详情</a>
</div>
路由中我们还是这么写,但是给detail页面指定了一个controller
然后我们在controller.js里面
1
2
3
4
5
6
//注意,我们需要在路由最开头的依赖中加上myModule哦
var myModule = angular.module('myModule',[]);
myModule
.controller('DetailController',function($scope,$stateParams){
console.log($stateParams);
});
当我们在list页面中点击链接时,进入detail页面,效果如下
5475fa040001985b03310231.jpg
我们在controller中也能打印出传递的参数,这就很有意思了。我们可以在controller中根据传递过来的参数和后台服务器进行通信然后把返回的结果绑定在scope上,页面是不是就可以显示出来了呢,比如这样
1
2
3
4
5
6
7
myModule.controller('DetailController', function($scope,$stateParams){
console.log($stateParams);
$http.post('API_URL',{params:$stateParams})
.success(function(data,status,headers,config){
$scope.content = data;
});
})
我们通过http服务把$stateParams发送到后台,然后把返回的数据绑定在$scope.content上,detail.html中的{{content}}是不是就可以跟着变化了呢?
------------------------------------------------------------------------
今天就暂时写这么多,以上是最近实践路由的一些经验,但是路由的用法还可以更灵活,这需要我们掌握更多这方面的内容。
PS:今天有门课期末前两天不得不预习了整本书,缺了两天,但是我觉得应该反思,养成一个好习惯不容易,不应该为自己找各种理由,而且目测一般都挂科了……时间虽然紧,但挤挤肯定还是有的!
2014-11-27 回复 1
PHPBird
今天来说一点angularjs中看起来很简单但是实践起来又有不少问题的ng-class吧
------------------------------------------------------------------------
不过还是先说一下和angular无关的一个js的小坑,不知道大家遇到过没有,就是json格式的文件。之前一直都在js中定义json数组,或者从php后台用json_encode编码后直接返回,从没有自己写过json格式的数据,今天就遇到点麻烦。
在js中定义json数组这么写就好了:
1
var arr = [{a:1,b:2},{a:5,b:10}];
但是在json文件中千万不能这么写
1
[{a:1,b:2},{a:5,b:10}]
必须给key加上引号才行哦。今天调试好久才发现这个问题,也算个教训吧……
------------------------------------------------------------------------
然后说ng-class这个东西,老师讲的时候一句带过,用的时候还是需要费些时间的。
我总结了一下通过ng-class给元素动态地加class有4种做法,下面一个一个来说。
先看一下官方的说明
547747ed00019d2705000171.jpg
不知道大家能不能看清,给个链接吧https://code.angularjs.org/1.3.0-beta.11/docs/api/ng/directive/ngClass
大致翻译一下就是说ng-class指令有3中操作方式,通过ng-class等于的表达式计算出来的值的类型来决定是哪种
方式1: 当它的值为一个字符串时,它就会把用空格分开的字符串加到class中
方式2: 当值为一个数组时,它每个字符串元素都会被加到class中
方式3: 当值为一个对象时(key=>value),把value为true的key加到class中
首先是最不推荐的
1
2
3
4
5
6
7
<div ng-class="{{myclass}}"></div>
....
<script>
function someController($scope){
$scope.myclass = "xxx";
}
</script>
上面这种方法效果上来说没问题,但是完全没必要用ng-class,普通的也能实现这个效果。而且在controller中控制样式总感觉有点儿别扭……
然后说另一种用法
1
<div ng-class="{true :'red', false :'green'}[someVariable]"></div>
这种用法就是说variable为true时,就给元素加上red这个class,如果variable为false就加上green这个class,这个在逻辑比较简单的时候还是蛮好用的。
下一种适合需要添加多个类的时候,也就是ng-class的值为一个对象
1
2
3
4
5
6
<p ng-class="{strike: deleted, bold: important, red: error}">Map Syntax Example</p>
<input type="checkbox" ng-model="deleted"> deleted (apply "strike" class)
<br>
<input type="checkbox" ng-model="important"> important (apply "bold" class)
<br>
<input type="checkbox" ng-model="error"> error (apply "red" class)
上面代码ng-class就是一个对象,我们把deleted,important,error进行双向数据绑定,当我们在checkbox勾选时,它们变为true,然后对应的key就被加到class中,效果图
547749e500016b1f02880112.jpg
还有一种就是数组类型的,数组都每个字符串元素都会被加到class中
1
2
3
4
5
6
<p ng-class="[style1, style2, style3]">Using Array Syntax</p>
<input ng-model="style1" placeholder="Type: bold, strike or red">
<br>
<input ng-model="style2" placeholder="Type: bold, strike or red">
<br>
<input ng-model="style3" placeholder="Type: bold, strike or red">
当我们在样式中定义好bold,strike,red;类的样式后,我们输入这些字符串就会出现效果
54774a860001390801760135.jpg
大概就是这几种用法,我推荐大家用对象来添加对象,那样最好控制逻辑也清楚。
------------------------------------------------------------------------------
今天就分享这些吧,希望对大家有些帮助
2014-11-28 回复 1
purple_yao
总结得很好,谢谢分享出来。哈哈
2014-11-26 回复 0
flyysr
谢谢分享,我也在学这个,可以交流
2014-12-24 回复 0
em_heqian
谢谢分享心得 很有帮助
2015-01-14 回复 0
我好吗
感谢分享,看完之后了解很多
2015-03-17 回复 0
___Qie听风吟
controller如果被实例化过会有缓存的吗?
比如说我先进入index页,然后再点击登陆页,完成后自动跳到index页。但是index页的controller没有像第一次进出时数据的初始化
有什么办法让controller重新加载么
用的ui-router来做路由
2015-04-22 回复 0
菠萝小萝卜
哥们,你这问题解决了没?
#12015-09-21 回复
catdp
多谢分享,帮助很大!
2015-05-10 回复 0
TLE
谢谢分享,希望继续求教
2015-05-21 回复 0
chifanqu
请问大神ui-router能实现动画吗?
用ng-router时候,页面会自动获得ng-enter这个属性,ui-router可以实现吗
2015-06-01 回复 0
hapiman
可以分享哈你的代码么
2015-06-15 回复 0
飘逝的绝唱
感觉写的前后不连贯 可能是笔记的原因 跳跃性比较强 按照步骤没办法进行 只能给已经懂的人 加深印象
2015-06-18 回复 0
飘逝的绝唱
不过整体来说 是对大漠课堂的细致讲解
2015-06-18 回复 0
老徐徐
不错,写的很好
1天前
-----------------------------------------------------------------
由于路由是控制整个应用的显示状态的,所以我们要让路由模块第一时间接管整个应用。
使用ui-router很简单,下载它的包,在index.html中引入js文件,然后在模块的依赖中引入即可。
1
var routerApp = angular.module('routerApp', ['ui.router']);
ui-router的本质其实是向我们预留的部分填充模板,它会在页面中去寻找ui-view这条指令,然后根据当前页面状态把对应的模板填充到ui-view所在的区块中。
比如一个典型的页面是nav+footer固定不变,中间主要部分作为内容显示区域时常发生变化。对应的页面结构就是
1
2
3
4
5
<body>
<nav>This is nav</nav>
<div ui-view></div>
<footer>This is footer</footer>
</body>
然后我们的路由根据页面的状态,选择不同的html模板填充到ui-view的这个div里面。
在js中具体怎么使用ui-router呢
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
routerApp.config(function($stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise('/index');
$stateProvider
.state('index',{
url : '/index',
templateUrl : 'tpls/index.html'
})
.state('list',{
url : '/list',
templateUrl : 'tpls/list.html'
})
.state('detail',{
url : '/detail',
templateUrl : 'tpls/detail.html'
});
});
以上就是angular路由最基本的模板。但是要注意一个问题,state的第一个参数并不是匹配规则,而是叫状态名,也就是说这个参数事实上可以是任意的,它用来给当前状态增加一个名字,触发路由规则还是看url的内容。比如这样
1
2
3
4
.state('home',{
url : '/index',
templateUrl : 'tpls/index.html'
})
我们必须要地址栏输入www.xx.com/index,才会加载对应的模板而不是输入home,它仅仅是一个名字而已。
但是说,这个名字也是有它的作用的。看一个例子就明白了。
index.html
1
2
3
<nav>This is the nav</nav>
<div ui-view></div>
<footer>This is the footer</footer>
list.html
1
2
3
4
<div>
<p>this is the list page</p>
<div ui-view></div>
</div>
list-main.html
1
2
3
<div>
<p>This is list-main Page</p>
</div>
如果我们的路由这么写
1
2
3
4
5
6
7
8
.state('aaa',{
url : '/list',
templateUrl : 'tpls/list.html'
})
.state('bbb',{
url : '/list/main',
templateUrl : 'tpls/list-main.html'
})
那当我们在浏览器中输入www.xx.com/list/main的时候,页面结果为
5472d6ee0001fc2803350157.jpg
如果我们的路由这么写
1
2
3
4
5
6
7
8
.state('aaa',{
url : '/list',
templateUrl : 'tpls/list.html'
})
.state('aaa.bbb',{
url : '/main',
templateUrl : 'tpls/list-main.html'
})
那当我么输入www.xx.com/list/main的时候,页面结果为
5472d6fd0001ebcf03690177.jpg
也就是说state的的第一个参数为页面定义了一个名字,这个页面的模板只能放到它的父级中的ui-view去。如果没有.这种写法,那么默认的父级是index.html,所以第一种写法bbb模板的父级是index.html,所以输入/list/main时会把对应模板加载到index.html中的ui-view里面。而第二种写法aaa.bbb,这意思是说bbb的父级是aaa,所以bbb的模板要放到aaa模板(也就是list.html)中的ui-view中。这时的url是在aaa页面的url后的url。
当然还有页面的嵌套,这部分其实大漠老师在视频中已经讲得很清楚了。
这是路由需要注意的一个作用域问题。
-----------------------------------------------------------------------
当然路由还有很多其他问题,因为路由是angularjs中很重要的一部分,但基本的用法就是上面所讲的了,如果把所有静态页面都写好了,那么用以上的内容就已经能做出一个精美的web了。现在学习了路由的基本用法,其它问题的话我们碰到一个再解决一个吧。
2014-11-24AngularJSJavaScript9488 浏览15 回答
PHPBird
今天还是来说一下angular中的路由模块。我们实际项目中,各个页面的切换是经常会与Auth相关的。比如我网站的后台,是需要登录过的用户才能进去,那么我们用angularJS做前端路由的时候应该怎么完成这个功能呢
------------------------------------------------------------------------
我们还是先设想一个最简单的场景吧。我们的应用有两个页面,登录页面后内容页面,要求是必须要验证登录成功后才能进入内容页面,下面我们一起来实现一下这个例子吧。当然我觉得我的方法可能会比较Low,但是学习阶段我们能先把功能做出来比什么都重要。
首先用bootstrap来写一个简单的登录页面吧。具体bootstrap代码我就不说了,我们关注的是angular在这里面如何用起来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="col-md-offset-3 col-md-4">
<form class="form" role="form" name="loginForm" ng-submit="loginCheck()">
<div class="form-group">
<label class="control-label">用户名</label>
<input type="text" class="form-control" required placeholder="请输入管理员账号" ng-model="admin.username">
</div>
<div class="form-group">
<label class="control-label">密码</label>
<input type="password" class="form-control" ng-model="admin.pwd" required placeholder="请输入密码">
</div>
<div ng-show="showError" class="alert alert-danger alert-dismissible" role="alert">
<button ng-click="showError=false" type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">关闭</span></button>
用户名或密码错误!!你还有一次机会
</div>
<input type="submit" class="btn btn-primary btn-lg" value="登录" ng-disabled="loginForm.$invalid">
</form>
</div>
效果如下
54788faf000197b405000227.jpg
当然我之前还有一些css的布局,粘代码过去可能会出错哦,至少得在最外层加一个div class="row"
还可以看见,我给登录按钮加了个ng-disabled,当表单没有通过验证的时候是不能点登录的。
然后我加了一个提示的tips,用到了ng-show,在controller里会有一个showError的属性来控制它的显示,当验证账号密码错误时showError为true。
当我们验证出错的时候
547892c90001675104860298.jpg
接着我们来看一下路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var myApp = angular.module('myApp', ['ui.router','myModule']);
myApp.run(function($rootScope, $state, $stateParams){
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$rootScope.$state.isLogin = false;
});
myApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login',{
url : '/login',
templateUrl : 'tpls/login.html',
controller : 'LoginController'
})
.state('index',{
url : '/index',
templateUrl : 'tpls/index.html',
controllerProvider : function($rootScope){
if($rootScope.$state.isLogin == false){
$rootScope.$state.go('login');
}
return function(){};
}
});
}
因为在整个页面中我们都会用到登录状态,所以我把登录状态绑定到rootscope中,isLogin刚开始是false表示未登录。
接着看路由里面,login这个很简单,主要看index页面。
关键的一步就是index的controller,在这里我选择用controllerProvider的方式来生成controller,可以看到我们最后实际上是返回的一个空的function,但是在返回空controller之前(index页面还没有解析),我可以做一些事情,那就是验证权限啦!
如果$rootScope.$state.isLogin为false也就是还没有登录,那就直接跳转到登录页面。跳转用到了$state里面的go方法,go中的变量就是我们每个页面的状态名,也就是state的第一个参数。我是go('login'),它就跳转到state的第一个参数是login的那个页面去了,也就是登录页面。换句话说,如果我们登录提交后验证没有成功,当我们在地址栏输入/index的时候会跳到登录页面的哦。
那么再来看看我们的验证模块。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
myModule
.controller('LoginController', function($scope,$rootScope,$http){
$scope.showError = false;
$scope.loginCheck = function(){
var username = $scope.admin.username;
var pwd = $scope.admin.pwd;
var loginSuccess = false;
http.get('/acm-admin/data/user.json')
.success(function(response){
for(var i=0; i<response.length; i++){
if(response[i].username == username && response[i].pwd == pwd){
$rootScope.$state.isLogin = true;
loginSuccess = true;
$rootScope.$state.go('index');
}
}
if(!loginSuccess){
$scope.showError = true;
}
});
}
})
初始化我们给showError一个值为false,不要显示错误提示框。然后来看看验证登录的这个方法。首先获取到用户输入的用户名和密码,设置登录成功的状态的false。然后通过$http.get,到指定的地方去取一个json文件,很显然这是个假数据,我们把预设的用户名和密码存放到这个json文件中。取出预设的用户名和密码之后就和用户输入的来进行对比,相信这都很简单,大家肯定能看明白。如果用户名和密码都对上了,那么就把登录状态设置为true,登录成功也设置为true。然后用$state的go方法跳转到Index页面。
如果登录信息验证失败,那么就把showError赋为true,页面上就会显示提示信息咯。
----------------------------------------------------------------------------
怎么样,很简单吧。当然还有其它实现这一功能的方法,而且我上述的方法很可能还有诸多安全隐患,而且模块的分工也是不明确的,淡然实际部署不推荐这么写了。我们可以优化改进的地方很多,比如验证的模块是不是应该独立出去呢,或者用户有没有什么办法能轻易绕过这个登录保护呢?这就留待小伙伴们自己探究了……继续学习angular去了,大家晚安!!
2014-11-28 回复 2
PHPBird
其实路由的功能是比较复杂的,我们实际应用中页面的状态也是非常多的,上面简单的路由是肯定不能满足我们的需求的,所以我们必须要更深入地了解下路由以及它更有用的一些用法。
--------------------------------------------------------------------
首先来说一下templateUrl属性,上面说了它的值是对应模板的地址,比如
1
2
3
...
templateUrl : 'tpls/index.html',
...
但事实上我们也可以用一个函数作为值,但是这个函数必须返回模板的地址,比如
1
2
3
4
5
...
templateUrl : function(){
return 'tpls/index.html';
},
...
这两段代码的效果其实是一模一样的,很容易理解。但是我们在实际应用的时候会经常有这样的需求:在url里拼接get参数,然后后台利用get参数去读数据库然后返回相应的内容。这时候用第一种方法实现起来可能就不那么容易(但是也是能实现的),而用第二种方法就很容易了。
那么在这之前需要介绍一个很有用的东西叫做$stateParams,看名字也很容易理解,状态参量。这个东西就存储了页面状态的有关信息,我们通过一个例子来看看这到底是神马东东。
这是我们的list.html页面
1
2
3
4
5
<div>
<p>This is the list page</p>
<a ui-sref="detail({articleId:'111'})">文章详情</a>
</div>
这是detail.html页面
1
2
3
<div>
<p>This is the detail page</p>
</div>
这是路有部分了,注意看哟
1
2
3
4
5
6
7
8
9
10
11
.state('list',{
url : '/list',
templateUrl : 'tpls/list.html'
})
.state('detail',{
url : '/detail/{articleId}',
templateUrl : function($stateParams){
console.log($stateParams);
return 'tpls/detail.html';
}
})
先来看看效果,当我们进入list页面时是下面这个样子
5475f3190001e56403160176.jpg
我们点击文章详情这个链接后,页面变成了detail,并且下面打印出了$stateParams
5475f3190001aba903240258.jpg
这里我们发现它是一个对象,并且包含了我们所传递的参数。小伙伴们看看我上面是怎么在url里传递参数的哦,就是加一个括号,里面放一个我们要传递的对象即可。传递对象参数的时候需要注意,路由中url后面跟了多少参数你就只能传递那么多参数,比如
路由中这么写
1
2
3
4
5
6
7
.state('detail',{
url : '/detail/{articleId}/{else}',
templateUrl : function($stateParams){
console.log($stateParams);
return 'tpls/detail.html';
}
})
html页面中这么写
1
2
3
4
<div>
<p>This is the list page</p>
<a ui-sref="detail({articleId:'111',else:'imooc'})">文章详情</a>
</div>
那我们输出的效果就是这样的
5475f62c0001ec4303800275.jpg
怎么能用它呢?小伙伴们记得路由中的另一个参数controller,它为模板指定了一个controller,事实上我们可以把$stateParams传入controller中,看个例子吧
首先我们在index.html引入controller.js
list页面和上面没有变化
1
2
3
4
<div>
<p>This is the list page</p>
<a ui-sref="detail({articleId:'111',else:'imooc'})">文章详情</a>
</div>
路由中我们还是这么写,但是给detail页面指定了一个controller
然后我们在controller.js里面
1
2
3
4
5
6
//注意,我们需要在路由最开头的依赖中加上myModule哦
var myModule = angular.module('myModule',[]);
myModule
.controller('DetailController',function($scope,$stateParams){
console.log($stateParams);
});
当我们在list页面中点击链接时,进入detail页面,效果如下
5475fa040001985b03310231.jpg
我们在controller中也能打印出传递的参数,这就很有意思了。我们可以在controller中根据传递过来的参数和后台服务器进行通信然后把返回的结果绑定在scope上,页面是不是就可以显示出来了呢,比如这样
1
2
3
4
5
6
7
myModule.controller('DetailController', function($scope,$stateParams){
console.log($stateParams);
$http.post('API_URL',{params:$stateParams})
.success(function(data,status,headers,config){
$scope.content = data;
});
})
我们通过http服务把$stateParams发送到后台,然后把返回的数据绑定在$scope.content上,detail.html中的{{content}}是不是就可以跟着变化了呢?
------------------------------------------------------------------------
今天就暂时写这么多,以上是最近实践路由的一些经验,但是路由的用法还可以更灵活,这需要我们掌握更多这方面的内容。
PS:今天有门课期末前两天不得不预习了整本书,缺了两天,但是我觉得应该反思,养成一个好习惯不容易,不应该为自己找各种理由,而且目测一般都挂科了……时间虽然紧,但挤挤肯定还是有的!
2014-11-27 回复 1
PHPBird
今天来说一点angularjs中看起来很简单但是实践起来又有不少问题的ng-class吧
------------------------------------------------------------------------
不过还是先说一下和angular无关的一个js的小坑,不知道大家遇到过没有,就是json格式的文件。之前一直都在js中定义json数组,或者从php后台用json_encode编码后直接返回,从没有自己写过json格式的数据,今天就遇到点麻烦。
在js中定义json数组这么写就好了:
1
var arr = [{a:1,b:2},{a:5,b:10}];
但是在json文件中千万不能这么写
1
[{a:1,b:2},{a:5,b:10}]
必须给key加上引号才行哦。今天调试好久才发现这个问题,也算个教训吧……
------------------------------------------------------------------------
然后说ng-class这个东西,老师讲的时候一句带过,用的时候还是需要费些时间的。
我总结了一下通过ng-class给元素动态地加class有4种做法,下面一个一个来说。
先看一下官方的说明
547747ed00019d2705000171.jpg
不知道大家能不能看清,给个链接吧https://code.angularjs.org/1.3.0-beta.11/docs/api/ng/directive/ngClass
大致翻译一下就是说ng-class指令有3中操作方式,通过ng-class等于的表达式计算出来的值的类型来决定是哪种
方式1: 当它的值为一个字符串时,它就会把用空格分开的字符串加到class中
方式2: 当值为一个数组时,它每个字符串元素都会被加到class中
方式3: 当值为一个对象时(key=>value),把value为true的key加到class中
首先是最不推荐的
1
2
3
4
5
6
7
<div ng-class="{{myclass}}"></div>
....
<script>
function someController($scope){
$scope.myclass = "xxx";
}
</script>
上面这种方法效果上来说没问题,但是完全没必要用ng-class,普通的也能实现这个效果。而且在controller中控制样式总感觉有点儿别扭……
然后说另一种用法
1
<div ng-class="{true :'red', false :'green'}[someVariable]"></div>
这种用法就是说variable为true时,就给元素加上red这个class,如果variable为false就加上green这个class,这个在逻辑比较简单的时候还是蛮好用的。
下一种适合需要添加多个类的时候,也就是ng-class的值为一个对象
1
2
3
4
5
6
<p ng-class="{strike: deleted, bold: important, red: error}">Map Syntax Example</p>
<input type="checkbox" ng-model="deleted"> deleted (apply "strike" class)
<br>
<input type="checkbox" ng-model="important"> important (apply "bold" class)
<br>
<input type="checkbox" ng-model="error"> error (apply "red" class)
上面代码ng-class就是一个对象,我们把deleted,important,error进行双向数据绑定,当我们在checkbox勾选时,它们变为true,然后对应的key就被加到class中,效果图
547749e500016b1f02880112.jpg
还有一种就是数组类型的,数组都每个字符串元素都会被加到class中
1
2
3
4
5
6
<p ng-class="[style1, style2, style3]">Using Array Syntax</p>
<input ng-model="style1" placeholder="Type: bold, strike or red">
<br>
<input ng-model="style2" placeholder="Type: bold, strike or red">
<br>
<input ng-model="style3" placeholder="Type: bold, strike or red">
当我们在样式中定义好bold,strike,red;类的样式后,我们输入这些字符串就会出现效果
54774a860001390801760135.jpg
大概就是这几种用法,我推荐大家用对象来添加对象,那样最好控制逻辑也清楚。
------------------------------------------------------------------------------
今天就分享这些吧,希望对大家有些帮助
2014-11-28 回复 1
purple_yao
总结得很好,谢谢分享出来。哈哈
2014-11-26 回复 0
flyysr
谢谢分享,我也在学这个,可以交流
2014-12-24 回复 0
em_heqian
谢谢分享心得 很有帮助
2015-01-14 回复 0
我好吗
感谢分享,看完之后了解很多
2015-03-17 回复 0
___Qie听风吟
controller如果被实例化过会有缓存的吗?
比如说我先进入index页,然后再点击登陆页,完成后自动跳到index页。但是index页的controller没有像第一次进出时数据的初始化
有什么办法让controller重新加载么
用的ui-router来做路由
2015-04-22 回复 0
菠萝小萝卜
哥们,你这问题解决了没?
#12015-09-21 回复
catdp
多谢分享,帮助很大!
2015-05-10 回复 0
TLE
谢谢分享,希望继续求教
2015-05-21 回复 0
chifanqu
请问大神ui-router能实现动画吗?
用ng-router时候,页面会自动获得ng-enter这个属性,ui-router可以实现吗
2015-06-01 回复 0
hapiman
可以分享哈你的代码么
2015-06-15 回复 0
飘逝的绝唱
感觉写的前后不连贯 可能是笔记的原因 跳跃性比较强 按照步骤没办法进行 只能给已经懂的人 加深印象
2015-06-18 回复 0
飘逝的绝唱
不过整体来说 是对大漠课堂的细致讲解
2015-06-18 回复 0
老徐徐
不错,写的很好
1天前
发表评论
-
Angularjs: How to display loading-icon when using 'resolve' in $routeProvider?
2015-12-04 17:28 107833down votefavorite ... -
带你走近AngularJS - 基本功能介绍
2015-12-01 18:15 706带你走近AngularJS系列: 带你走近Angular ... -
angularjs过滤器(number)
2015-12-01 10:37 1156摘要 angularjs过滤器number,用来精确浮点数 ... -
angularjs 的select设置默认值
2015-11-02 15:39 2983myAppModule.controller ... -
AngularJS 验证信息框架的封装
2015-10-31 16:15 1258AngularJS 的表单验证规则 angular ... -
angularjs reset input file and filter file
2015-10-31 11:51 1768文件上传开发模板 <form id="up ... -
angular.foreach 循环方法使用指南
2015-10-29 10:21 1229angular有自己的生命周期。循环给一个 angul ... -
AngularJS 最常用的八种功能
2015-10-22 17:54 950本文地址:http://zhaoyanblog.com/ar ... -
AngularJS select详细用法
2015-10-22 17:51 2119select 是 AngularJS 预设的一组direc ... -
angularjs 密码一致性校验
2015-10-19 11:29 751angularjs 校验密码字段一致性 Js代 ... -
AngularJS去掉的URL里的#号
2015-10-14 18:57 818时间 2014-08-14 21:59:38 粉丝日 ... -
AngularJS ui-router (嵌套路由)
2015-10-14 16:50 767阅读目录 介绍 背景 实战 An ...
相关推荐
AngularJS UI.Router是一个强大的路由模块,它为AngularJS应用...通过这个项目,你可以学习到如何定义状态、设置视图、处理参数以及管理嵌套的路由层次。这对于构建功能丰富的单页应用程序(SPA)来说是非常有价值的。
**AngularJS学习手册源代码详解** AngularJS,作为Google维护的一款强大的前端JavaScript框架,自2009年发布以来,已经在Web开发领域产生了深远影响。它通过MVC(Model-View-Controller)架构模式,提供了丰富的...
在本项目中,"Maven之Spring Boot_angularJS--路由版"是一个综合性的Web应用开发实例,结合了三个核心的技术栈:Maven、Spring Boot和AngularJS。这个项目的目标是构建一个现代化的单页应用程序(SPA),通过...
**AngularJS 框架详解** AngularJS 是一个强大的JavaScript框架,由Google维护,用于构建动态Web应用。它通过MVC(模型-视图-控制器...通过深入学习和实践,你可以有效地利用AngularJS构建高效、可维护的Web应用程序。
在本“AngularJS路由”示例中,我们将探讨如何设置和使用AngularJS的路由系统。 首先,我们需要引入AngularJS库和`ngRoute`模块。`ngRoute`是AngularJS官方提供的路由模块,提供了一套完整的路由解决方案。在HTML...
### AngularJS 学习资料详解 #### 一、AngularJS简介与重要性 AngularJS是一种广泛使用的开源前端JavaScript框架,由Google维护。它主要用于构建单页面应用(SPA),通过简化客户端和服务器之间的交互来提高用户...
在AngularJS中,路由(Route)是实现页面导航和视图管理的关键组件。本教程将深入探讨AngularJS中的路由功能,以及如何在实际项目中应用。 路由在AngularJS中由`ngRoute`模块提供,它允许我们在不同的URL和视图之间...
### 四、AngularJs学习笔记 学习笔记通常包含个人对AngularJS理解的深入点,可能包括一些高级话题,如脏检查(Dirty Checking)、$digest循环,以及如何优化性能。笔记可能还包括解决常见问题的方法,以及作者在...
AngularJS的学习资料众多,其中"AngularJS学习 chm 文件"是一个方便快捷的学习资源。 CHM文件,全称是Compiled HTML Help,是一种由Microsoft开发的帮助文件格式。它将HTML页面、索引和图像等资源打包在一起,形成...
AngularJS学习笔记是一份个人学习AngularJS过程的记录和总结,内容涵盖了AngularJS的基础概念、组件、服务、指令、过滤器、路由等各个方面。 AngularJS的核心特点之一是数据双向绑定,这允许开发者将数据模型和视图...
AngularJS 嵌套路由:这是我针对同一个主题(ui-router)的第二篇文章. 如果你对第一篇文章感兴趣的话,可以访问 这里. 好了,让我们继续吧,来看看嵌套的ui-router状态是怎么回事. ui-router和同属AngularJS框架一...
在AngularJS中,`$route`服务是路由管理的核心组件,它允许开发者定义和管理应用程序的不同视图(views)与URL之间的映射。在本教程中,我们将深入探讨`$route`路由的基本概念、配置以及如何在实践中应用。 ### 1. ...
路由概念在单页面应用中非常关键,AngularJS的路由机制允许应用在不同的视图之间切换而不重新加载整个页面。笔记中讲解了如何在AngularJS中定义路由以及如何处理业务逻辑。 除了基础功能,AngularJS还提供了一些...
这个压缩包包含了AngularJS学习的全链条资料,无论你是初学者还是有一定经验的开发者,都能从中受益。通过系统学习和实践,你将能够熟练掌握AngularJS,构建出功能强大、用户体验优良的Web应用。
学习并掌握在AngularJS中传递路由参数是开发复杂应用的基础,这使得我们可以根据用户的选择或行为动态地加载和展示数据。结合其他AngularJS特性,如指令和服务,可以构建出强大的交互式前端应用。如果你对AngularJS...
**AngularJS路由详解** AngularJS,作为一款强大的前端JavaScript框架,其路由系统是构建单页面应用程序(SPA)的核心部分。路由允许我们通过URL来管理应用的不同视图和功能,实现页面间的平滑导航,而无需刷新整个...
总之,这个项目结合了AngularJS的前端能力、路由管理,以及.NET和Visual Studio的后端支撑,为初学者提供了一个良好的学习和实践平台。通过这个项目,你可以学习到如何在VS环境下构建一个完整的Web应用程序,掌握...
AngularJS,是由Google...总之,这个压缩包中的资料是一个全面的AngularJS学习资源库,无论你是初学者还是有一定经验的开发者,都能从中找到有价值的信息,提升你的AngularJS技能。祝你在学习的道路上取得丰硕的成果!
在《AngularJS学习笔记.chm》中,读者可以期待找到关于这些概念的深入解释,包括如何创建AngularJS项目,设置模块,编写控制器,使用指令,以及进行数据绑定和依赖注入的实例。此外,还可能涉及如何调试、优化...