- 浏览: 506969 次
- 性别:
- 来自: 上海
-
文章分类
- 全部博客 (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 111233down votefavorite ... -
带你走近AngularJS - 基本功能介绍
2015-12-01 18:15 726带你走近AngularJS系列: 带你走近Angular ... -
angularjs过滤器(number)
2015-12-01 10:37 1187摘要 angularjs过滤器number,用来精确浮点数 ... -
angularjs 的select设置默认值
2015-11-02 15:39 3006myAppModule.controller ... -
AngularJS 验证信息框架的封装
2015-10-31 16:15 1277AngularJS 的表单验证规则 angular ... -
angularjs reset input file and filter file
2015-10-31 11:51 1790文件上传开发模板 <form id="up ... -
angular.foreach 循环方法使用指南
2015-10-29 10:21 1261angular有自己的生命周期。循环给一个 angul ... -
AngularJS 最常用的八种功能
2015-10-22 17:54 979本文地址:http://zhaoyanblog.com/ar ... -
AngularJS select详细用法
2015-10-22 17:51 2150select 是 AngularJS 预设的一组direc ... -
angularjs 密码一致性校验
2015-10-19 11:29 769angularjs 校验密码字段一致性 Js代 ... -
AngularJS去掉的URL里的#号
2015-10-14 18:57 836时间 2014-08-14 21:59:38 粉丝日 ... -
AngularJS ui-router (嵌套路由)
2015-10-14 16:50 788阅读目录 介绍 背景 实战 An ...
相关推荐
笔记部分可能涵盖了作者在学习过程中的理解、心得和常见问题解决方案,对于初学者来说,这是一个宝贵的资源,可以帮助快速理解和解决实际问题。 在学习AngularJS时,建议先从基础概念入手,然后逐步深入到高级特性...
在这款自习程序中,AngularJS可能被用来处理用户交互、路由管理和数据模型的动态更新。 Ionic框架是专为移动应用设计的HTML5开发框架,它结合了AngularJS和Cordova(PhoneGap)的技术,允许开发者使用Web技术(HTML...
其功能包括让用户创建和共享笔记,这表明该应用具有用户交互性,用户不仅可以保存自己的学习心得,还能分享给其他用户,从而促进知识交流和社区互动。 **标签分析:** "JavaScript"标签揭示了这个项目的核心编程...
总的来说,angular-utils-ui-breadcrumbs提供了一个简单易用的面包屑导航解决方案,通过与UIRouter的结合,可以轻松地在AngularJS应用中实现具有动态路由信息的面包屑导航。通过自定义配置和模板,开发者可以灵活地...
Rocky Linux 8.10内核包
内容概要:本文档详细介绍了如何在Simulink中设计一个满足特定规格的音频带ADC(模数转换器)。首先选择了三阶单环多位量化Σ-Δ调制器作为设计方案,因为这种结构能在音频带宽内提供高噪声整形效果,并且多位量化可以降低量化噪声。接着,文档展示了具体的Simulink建模步骤,包括创建模型、添加各个组件如积分器、量化器、DAC反馈以及连接它们。此外,还进行了参数设计与计算,特别是过采样率和信噪比的估算,并引入了动态元件匹配技术来减少DAC的非线性误差。性能验证部分则通过理想和非理想的仿真实验评估了系统的稳定性和各项指标,最终证明所设计的ADC能够达到预期的技术标准。 适用人群:电子工程专业学生、从事数据转换器研究或开发的技术人员。 使用场景及目标:适用于希望深入了解Σ-Δ调制器的工作原理及其在音频带ADC应用中的具体实现方法的人群。目标是掌握如何利用MATLAB/Simulink工具进行复杂电路的设计与仿真。 其他说明:文中提供了详细的Matlab代码片段用于指导读者完成整个设计流程,同时附带了一些辅助函数帮助分析仿真结果。
内容概要:该题库专为研究生入学考试计算机组成原理科目设计,涵盖名校考研真题、经典教材课后习题、章节题库和模拟试题四大核心模块。名校考研真题精选多所知名高校的计算机组成原理科目及计算机联考真题,并提供详尽解析,帮助考生把握考研命题趋势与难度。经典教材课后习题包括白中英《计算机组成原理》(第5版)和唐朔飞《计算机组成原理》(第2版)的全部课后习题解答,这两部教材被众多名校列为考研指定参考书目。章节题库精选代表性考题,注重基础知识与重难点内容,帮助考生全面掌握考试大纲要求的知识点。模拟试题依据历年考研真题命题规律和热门考点,精心编制两套全真模拟试题,并附标准答案,帮助考生检验学习成果,评估应试能力。 适用人群:计划参加研究生入学考试并报考计算机组成原理科目的考生,尤其是需要系统复习和强化训练的学生。 使用场景及目标:①通过研读名校考研真题,考生可以准确把握考研命题趋势与难度,有效评估复习成效;②通过经典教材课后习题的练习,考生可以巩固基础知识,掌握解题技巧;③通过章节题库的系统练习,考生可以全面掌握考试大纲要求的各个知识点,为备考打下坚实基础;④通过模拟试题的测试,考生可以检验学习成果,评估应试能力,为正式考试做好充分准备。 其他说明:该题库不仅提供详细的题目解析,还涵盖了计算机组成原理的各个方面,包括计算机系统概述、数据表示与运算、存储器分层、指令系统、中央处理器、总线系统和输入输出系统等。考生在使用过程中应结合理论学习与实践操作,注重理解与应用,以提高应试能力和专业知识水平。
__UNI__DB9970A__20250328141034.apk.1
rust for minio
国网台区终端最新规范
资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。
一个简单的机器学习代码示例,使用的是经典的鸢尾花(Iris)数据集,通过 Scikit-learn 库实现了一个简单的分类模型。这个代码可以帮助你入门机器学习中的分类任务。
pyqt离线包,pyqt-tools离线包
资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。
SQL常用日期和时间函数整理及在sqlserver测试示例 主要包括 1.查询当前日期GETDATE 2.日期时间加减函数DATEADD 3 返回两个日期中指定的日期部分之间的差值DATEDIFF 4.日期格式转换CONVERT(VARCHAR(10),GETDATE(),120) 5.返回指定日期的年份数值 6.返回指定日期的月份数值 7.返回指定日期的天数数值
GSDML-V2.3-Turck-BL20_E_GW_EN-20160524-010300.xml
T_CPCIF 0225-2022 多聚甲醛.docx
《基于YOLOv8的智能仓储货物堆码倾斜预警系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计
蚕豆脱壳机设计.zip
台区终端电科院送检文档