AngularJS路由和模板

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/

AngularJS-route

前言

如果想开发一款类似gmail的web应用,我们怎么做呢?

以jQuery的思路,做响应式的架构设计时,我们要监听所有点击事件,通过事件函数触发我们加载数据,提交,弹框,验证等的功能;以 AngularJS的思路,做声明式的架构设计时,我们通过指令和路由先设定好,什么样的操作干什么事情,等事件发生时,程序就会知道该干什么了。

今天说一下,AngularJS是如何实现前端路由功能的!

目录

  1. AngularJS路由介绍
  2. 路由的代码实现
  3. 实现效果截图

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转向的结果。

AngularJS-route1

点击ID2的链接。

AngularJS-route2

页面被刷新了,出了detil的页面。同时,我们注意观察,页面没有整个刷新,而在视图中(ng-view)做的局部刷新。因为,chrome的开发工具的监控中,只是看到detail.html被加载。

我们再浏览地址栏中,输入212

http://localhost:9000/demo-route.html#/list/212

AngularJS-route3

观察chrome的开发工具的监控中,没有任何的networking操作。

在浏览地址栏中,再输入原来list的地址

http://localhost:9000/demo-route.html#/list

观察chrome的开发工具的监控,确认没有任何变化!!

从这个实验,我们看到AngularJS纯前端路由的实现思路,配合视图的局部刷新,把业务功能切片后分散到HTML的模板页面中。非常容易地实现了widget。并且,这种widget可重用性会非常高,能大大减少前端代码量。

后端组件化开发思路,流畅的嵌入前端。爽死啦!!!

转载请注明出处:
http://blog.fens.me/angularjs-route-template/

打赏作者

This entry was posted in Javascript语言实践, 架构设计

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

35 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
jiyinyiyong

Angular 觉得好难懂.. View, subView 概念基本都颠覆了
View 之间的消息传递在 Angular 也找不着对应的,, 似乎都跟不上了

Conan Zhang

完全后台的开发思路,你有时间了解一个Java的Spring,再学Angular就容易多了。几乎是一个大模子出来的。

jiyinyiyong

想不到会跑这么远.. 印象里 Spring 是后端 MVC 呀

Conan Zhang

Angular这种架构的设计思路,应该源于后端开发架构。

Spring中也有IOC, DataBinding, Service, Component这些概念都。与Angular基于是一样的设计思路。我曾经也尝试过,用后端架构来设计前端应用,Angular的真的很巧妙!

相比jQuery也似乎,对应后端架构的消息系统(MQ)。

jiyinyiyong

我的后端开发经验只有 CNodeJS 的 Node 部分代码…
感觉上, 即便是 Backbone 的 MV* 和后端的 MVC 差距也非常大啊.
要再看下…

lyman

我觉得所有这些概念都是次要的,核心还是写这些代码过程中,我们是不是觉得爽。。。

jiyinyiyong

其实也是对实际的场景, 工具是否合适的问题啦

lyman

view之间似乎不应该直接传消息~~也许应该用emit来传输或者用某个中介来传输。。。

jiyinyiyong

嗯, Backbone 当中, 嵌套直接传, 否则用中介.. 中介更好..
Angular 呢?

lyman

其实这些都是在实际写项目,开发代码过程中,一步步尝试及感觉的。比如你觉得直接传递或者直接放到$rootScope中觉得太恶心了,你就会想放到某个中间件去,比如搞个service之类的。
我是觉得backbone搞了半天,没让我觉得fancy在哪里,之前我一直看backbone资料,看了大半年。。资料越看越多。。甚至在翻译Anddy的Backbone Fundametal.及Marionatte的资料。结果大半年还没写出什么自己喜欢的代码。
而用Angularjs似乎我看完官方文档及一些周边资料没花一周,然后就马上开发出个demo了。而且自己很喜欢这样的代码。

jiyinyiyong

我是因为在维护基于 Backbone 的应用, 一直在体会起功能,
觉得从应用的思路上, View 之间的嵌套, 事件, 相对非常清晰,
问题也出在这些清晰的部分都需要手动维护, 甚至消耗性能,,,

Angular 的话, 没有完全对应的概念, View 和 Model 双向绑定,,
至于怎么用这个东西来组合成大的应用, 就觉得摸不着路了..
要说 fancy 的确是 Angular.

jia58960

博主熟悉ui-router吗?希望博主有时间写一个关于ui-router的用法。。。

Conan Zhang

ui-router指的是?

jia58960
Conan Zhang

等有时间吧!

我目前用文章中介绍的路由方式,已经构建了一套系统了。等做到权限部分的时候,会进行重构,可能会考虑用angluar-ui-router

binger

直接刷新浏览器会出错是什么原因,求解答!

binger

点击完列表后,再刷新浏览器报400的错 ,是什么原因

Conan Zhang

是不是版本的问题?
最新的angularjs,router单独实现了,直接用文章的代码会不兼容。

Tango

用yo angular构建项目以后,就直接拷贝粘贴你文章中的五个修改的地方,到那时grunt server以后还是跳到了index.html啊,而且ng-view里面的东西根本没有出来,是为什么呢……应该没有其他东西要设置了吧,ng-view和angular route这部分我自己搞了很多试验不知道为什么ng-view就是没东西出来……

Conan Zhang

可能是因为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)

对应再找一下,相关的文档吧。

Tango

上网找了下原来就是少了ngRoute…………谢谢啊……

anne

0.0 那个#弄不明白是哪里来的,吐血,不知道angular 是怎么解析路由的

Conan Zhang

angular已经升级了,本文不适合于最新的版本。
关于#号的处理,可以参考下文:
http://blog.fens.me/angularjs-url/

anne

0.0 额 糊里糊涂地,页面弄好了哈。我还是挺喜欢 #,它看起来好酷。。。

Hisheng

为什么点浏览器后退视图没有发生变化呢?

Conan Zhang

angular的ng-route调用了html5的history,后退动作要检查你的angular的怎么用的。

Kris Mao

作者有没有遇到过 用ui-router的时候,在网速慢的情况下,直接url跳转到配置的templateUrl上面去,并且css什么都没有加载,类似下图的情况啊?

Conan Zhang

有,css有时会没有被加载。尽量让CSS在index.html的首页加载,第一次打开会比较慢,但后面页面跳转会很顺畅。

高小红

我配置的根本就点击不了,不知道是哪里弄错了吗?求指导,谢谢!

Conan Zhang

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 谢谢!

Conan Zhang

抱歉回复晚了,你可以加QQ群383275651,进行交流。谢谢。

Kris Mao

接上回复

sdfse

三步四步都写的不错!

Conan Zhang

angular已经升级了,本文对于新版本angular是不太适用的。

35
0
Would love your thoughts, please comment.x
()
x