AngularJS体验式编程系列文章,将介绍如何用angularjs构建一个强大的web前端系统。angularjs是由Google团队开发的一款非常优秀web前端框架。在当前如此多的web框架下,angularjs能脱颖而出,从架构设计上就高人一等,双向数据绑定,依赖注入,指令,MVC,模板。Angular.js创新地把后台技术融入前端开发,扫去jQuery一度的光芒。用angularjs就像写后台代码,更规范,更结构化,更可控。
关于作者
- 张丹(Conan), 程序员Java,R,PHP,Javascript
- weibo:@Conan_Z
- blog: http://blog.fens.me
- email: bsspirit@gmail.com
转载请注明出处:
http://blog.fens.me/angularjs-route-template/
前言
如果想开发一款类似gmail的web应用,我们怎么做呢?
以jQuery的思路,做响应式的架构设计时,我们要监听所有点击事件,通过事件函数触发我们加载数据,提交,弹框,验证等的功能;以 AngularJS的思路,做声明式的架构设计时,我们通过指令和路由先设定好,什么样的操作干什么事情,等事件发生时,程序就会知道该干什么了。
今天说一下,AngularJS是如何实现前端路由功能的!
目录
- AngularJS路由介绍
- 路由的代码实现
- 实现效果截图
1. AngularJS路由介绍
AngularJS路由功能是一个纯前端的解决方案,与我们熟悉的后台路由不太一样。后台路由,通过不同的URL会路由到不同的控制器上(controller),再渲染(render)到页面(HTML)。AngularJS的前端路由,需求提前对指定的(ng-app),定义路由规则(routeProvider),然后通过不同的URL,告诉(ng-app)加载哪个页面(HTML),再渲染到(ng-app)视图(ng-view)中。
AngularJS的前端路由,虽然URL输入不一样,页面展示不一样,其实完成的单页(ng-app)视图(ng-view)的局部刷新。这样来看,AngularJS做单页应用就有点标配的感觉了。
从这个角度想想,要实现一个gmail的应用,真的就不难了。
2. 路由的代码实现
理论不多说了,直接上代码!! 还是基于我们之前用yeoman构建的项目。
业务场景:论坛功能,帖子列表页(list.html) 和 帖子内容页(detail.html)。
代码文件:
- 1. 增加:app/demo-route.html
- 2. 增加:app/views/route/list.html
- 3. 增加:app/views/route/detail.html
- 4. 修改: app/scripts/app.js
- 5. 修改: app/scripts/controllers/main.js
1). 增加:app/demo-route.html
这个文件是主页面(ng-app),包含视图(ng-view)
<!doctype html>
<head>
<meta charset="utf-8">
<title>route</title>
</head>
<body ng-app="routeApp">
<h1>Route Demo index</h1>
<div ng-view></div>
<script src="bower_components/angular/angular.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/controllers/main.js"></script>
</body>
</html>
2). 增加:app/views/route/list.html
这个页面是布局模板,是HTML的代码片段。包括了一组ID的列表,通过ID列表的链接,可以进入到ID的详细页面。
<hr/>
<h3>Route : List.html</h3>
<ul>
<li ng-repeat="id in [1, 2, 3 ]">
<a href="#/list/{{ id }}"> ID{{ id }}</a>
</li>
</ul>
3). 增加:app/views/route/detail.html
这个页面是布局模板,是HTML的代码片段。通过ID访问,包含ID号, (ID的文章内容)
<hr/>
<h3>Route <span style="color: red;">{{id}}</span>: detail.html </h3>
4). 修改: app/scripts/app.js
这个是ng-app文件的定义,我们在demo-route.html中定义了routeApp,在这里需要声明。
var routeApp = angular.module('routeApp',[]);
routeApp.config(['$routeProvider',function ($routeProvider) {
$routeProvider
.when('/list', {
templateUrl: 'views/route/list.html',
controller: 'RouteListCtl'
})
.when('/list/:id', {
templateUrl: 'views/route/detail.html',
controller: 'RouteDetailCtl'
})
.otherwise({
redirectTo: '/list'
});
}]);
在routeApp模块中,我们定义了路由和布局模板。routeApp的默认URL是/list,即http://localhost:9000/demo-route.html#/list。 跳转详细页的路由是/list/:id,id为参数。
同时,/list的布局模板是views/route/list.html,属于RouteListCtl的控制器管理空间。
5). 修改: app/scripts/controllers/main.js
这个文件定义控制器controller。
routeApp.controller('RouteListCtl',function($scope) {
});
routeApp.controller('RouteDetailCtl',function($scope, $routeParams) {
$scope.id = $routeParams.id;
});
分别对应该路由中的两个控制器声明。
程序写好,我们打开浏览器看效果。
3. 实现效果截图
别忘了用下面命令,启动程序。
grunt server
浏览器被自动打开,默认出的是http://localhost:9000/demo-route.html#/list, “#/list”是被redirectTo转向的结果。
点击ID2的链接。
页面被刷新了,出了detil的页面。同时,我们注意观察,页面没有整个刷新,而在视图中(ng-view)做的局部刷新。因为,chrome的开发工具的监控中,只是看到detail.html被加载。
我们再浏览地址栏中,输入212
http://localhost:9000/demo-route.html#/list/212
观察chrome的开发工具的监控中,没有任何的networking操作。
在浏览地址栏中,再输入原来list的地址
http://localhost:9000/demo-route.html#/list
观察chrome的开发工具的监控,确认没有任何变化!!
从这个实验,我们看到AngularJS纯前端路由的实现思路,配合视图的局部刷新,把业务功能切片后分散到HTML的模板页面中。非常容易地实现了widget。并且,这种widget可重用性会非常高,能大大减少前端代码量。
后端组件化开发思路,流畅的嵌入前端。爽死啦!!!
Angular 觉得好难懂.. View, subView 概念基本都颠覆了
View 之间的消息传递在 Angular 也找不着对应的,, 似乎都跟不上了
完全后台的开发思路,你有时间了解一个Java的Spring,再学Angular就容易多了。几乎是一个大模子出来的。
想不到会跑这么远.. 印象里 Spring 是后端 MVC 呀
Angular这种架构的设计思路,应该源于后端开发架构。
Spring中也有IOC, DataBinding, Service, Component这些概念都。与Angular基于是一样的设计思路。我曾经也尝试过,用后端架构来设计前端应用,Angular的真的很巧妙!
相比jQuery也似乎,对应后端架构的消息系统(MQ)。
我的后端开发经验只有 CNodeJS 的 Node 部分代码…
感觉上, 即便是 Backbone 的 MV* 和后端的 MVC 差距也非常大啊.
要再看下…
我觉得所有这些概念都是次要的,核心还是写这些代码过程中,我们是不是觉得爽。。。
其实也是对实际的场景, 工具是否合适的问题啦
view之间似乎不应该直接传消息~~也许应该用emit来传输或者用某个中介来传输。。。
嗯, Backbone 当中, 嵌套直接传, 否则用中介.. 中介更好..
Angular 呢?
其实这些都是在实际写项目,开发代码过程中,一步步尝试及感觉的。比如你觉得直接传递或者直接放到$rootScope中觉得太恶心了,你就会想放到某个中间件去,比如搞个service之类的。
我是觉得backbone搞了半天,没让我觉得fancy在哪里,之前我一直看backbone资料,看了大半年。。资料越看越多。。甚至在翻译Anddy的Backbone Fundametal.及Marionatte的资料。结果大半年还没写出什么自己喜欢的代码。
而用Angularjs似乎我看完官方文档及一些周边资料没花一周,然后就马上开发出个demo了。而且自己很喜欢这样的代码。
我是因为在维护基于 Backbone 的应用, 一直在体会起功能,
觉得从应用的思路上, View 之间的嵌套, 事件, 相对非常清晰,
问题也出在这些清晰的部分都需要手动维护, 甚至消耗性能,,,
Angular 的话, 没有完全对应的概念, View 和 Model 双向绑定,,
至于怎么用这个东西来组合成大的应用, 就觉得摸不着路了..
要说 fancy 的确是 Angular.
博主熟悉ui-router吗?希望博主有时间写一个关于ui-router的用法。。。
ui-router指的是?
指的是这个 https://github.com/angular-ui/ui-router
等有时间吧!
我目前用文章中介绍的路由方式,已经构建了一套系统了。等做到权限部分的时候,会进行重构,可能会考虑用angluar-ui-router
直接刷新浏览器会出错是什么原因,求解答!
点击完列表后,再刷新浏览器报400的错 ,是什么原因
是不是版本的问题?
最新的angularjs,router单独实现了,直接用文章的代码会不兼容。
用yo angular构建项目以后,就直接拷贝粘贴你文章中的五个修改的地方,到那时grunt server以后还是跳到了index.html啊,而且ng-view里面的东西根本没有出来,是为什么呢……应该没有其他东西要设置了吧,ng-view和angular route这部分我自己搞了很多试验不知道为什么ng-view就是没东西出来……
可能是因为AngularJS升级的问题,最新版本的AngularJS路由ngRoute需要单独设置。
$routeProvider,还是可以用,除了要加上ngRoute,还要加上ngSanitize!
旧的
var app = angular.module(‘xx’, [‘ui.bootstrap’, ‘ngTable’]);
app .config([‘$routeProvider’, ‘$locationProvider’, function ($routeProvider, $locationProvider) {
新的
var app = angular.module(‘xx’, [‘ui.bootstrap’,’ngRoute’,’ngSanitize’,’ngTable’]);
app .config([‘$routeProvider’, ‘$locationProvider’, ‘$sceProvider’, function ($routeProvider, $locationProvider, $sceProvider)
对应再找一下,相关的文档吧。
上网找了下原来就是少了ngRoute…………谢谢啊……
0.0 那个#弄不明白是哪里来的,吐血,不知道angular 是怎么解析路由的
angular已经升级了,本文不适合于最新的版本。
关于#号的处理,可以参考下文:
http://blog.fens.me/angularjs-url/
0.0 额 糊里糊涂地,页面弄好了哈。我还是挺喜欢 #,它看起来好酷。。。
为什么点浏览器后退视图没有发生变化呢?
angular的ng-route调用了html5的history,后退动作要检查你的angular的怎么用的。
作者有没有遇到过 用ui-router的时候,在网速慢的情况下,直接url跳转到配置的templateUrl上面去,并且css什么都没有加载,类似下图的情况啊?
有,css有时会没有被加载。尽量让CSS在index.html的首页加载,第一次打开会比较慢,但后面页面跳转会很顺畅。
我配置的根本就点击不了,不知道是哪里弄错了吗?求指导,谢谢!
Angular新版本,要用ngRoute,在angular.module中增加ngRoute的配置,即可。
var app = angular.module(‘xx’, [‘ui.bootstrap’,’ngRoute’,’ngSanitize’,’ngTable’]);
app .config([‘$routeProvider’, ‘$locationProvider’, ‘$sceProvider’, function ($routeProvider, $locationProvider, $sceProvider)
好像和我描述的不太一样啊!可以加qq请教一下吗?我的qq:2371381048 谢谢!
抱歉回复晚了,你可以加QQ群383275651,进行交流。谢谢。
接上回复
三步四步都写的不错!
angular已经升级了,本文对于新版本angular是不太适用的。