这是"AngularJS – 七步从菜鸟到专家"系列的第七篇。

在第一篇,我们展示了如何开始搭建一个AngularaJS应用。在第四、五篇我们讨论了Angular内建的directives,上一篇了解了services的强大。

在这一章,我们来看几个前面没有机会细说的关键点,文章的最后会列举一些特别棒的学习资源链接和工具。

通过这整个系列的教程,我们会开发一个NPR(美国全国公共广播电台)广播的音频播放器,它能显示Morning Edition节目里现在播出的最新故事,并在我们的浏览器里播放。完成版的Demo可以看这里

7. Routing

在单页面应用中,视图之间的跳转就显尤为重要的,随着应用越来越复杂,我们需要用一种方法来精确控制什么时候该呈现怎样的页面给用户。

咱们可以通过在主页面中引入不同的模板来支持不同页面的切换,但是这么做的缺点就是,越来越多的内嵌代码导致最后难以管理。

通过ng-include指令我们可以把很多的模板整合在视图中,但是我们有更好的方法来处理这种情况,我们可以把视图打散成layout和模板视图,然后根据用户访问的特定的URL来显示需要的视图

我们可以将这些“碎片”在一个布局模板中拼接起来

AngularJS通过在$routeProvider($route服务的提供者)上声明routes来实现上面的构想

使用$routeProvider,我们可以更好的利用浏览历史的API并且可以让用户可以把当前路径存成书签以方便以后的使用

在我们的应用中设定路由,我们需要做两件事情:第一,我们需要指出我们存放将要存放新页面内容的布局模板在哪里。比如,如果我们想在所有页面都配上header和footer,我们可以这样设计布局模板:

1
2
3
4
5
6
7
8
9
<header>
  <h1>Header</h1>
</header>
<div class="content">
  <div ng-view></div>
</div>
<footer>
  <h5>Footer</h5>
</footer>

ng-view指令将高速$routeProvider在哪里渲染模板

第二,我们需要配置我们的路由信息,我们将在应用中配置$routeProvider

$routeProvider提供了两种方法处理路由:when和otherwise。 方法when接收两个参数,第一个设置$location.path(). (直接用“//”也没有问题)

第二个参数是配置对象,这个可以包含不同的键,我们可以简单的说几个

controller

1
2
3
4
5
controller: 'MyController'
// or
controller: function($scope) {
  // ...
}

如果在配置对象中设置了controller属性,那这个controller会在route加载的时候实例化,这个属性可以是一个字符串(必须在module中注册过的controller)也可以是controller function

Template模板

1
template: '<div><h2>Route</h2></div>'

如果我们在配置对象的template属性设置了值,那么模板就会被渲染到DOM中的ng-view处

templateUrl

1
templateUrl: 'views/template_name.html'

如果我们在配置对象的templateUrl属性中设置了值,AngularJS将通过XHR来获取该模板并把模板内容渲染到DOM中的ng-view处

值得注意的是:templateUrl属性跟其他AngularJS XHR请求的处理流程是一样的,也就是说,即使用户从这个页面离开,等他再回到这个页面,应用不会再去请求这个模板页面,因为$templateCache已经缓存了这个模板

添加一些路由

1
2
3
4
5
6
7
8
angular.module('myApp', []).
config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/', {
    controller: 'HomeController',
    template: '<h2>We are home</h2>'
  })
  .otherwise({redirectTo: '/'});
}]);

$routeProvider还可以处理URL里的传递的参数(比如,/people/42, 假设42是我们要找的people的id号) 只需要简单在字符串前加上 ‘:’,$routeProvider会尝试匹配URL中id并把id作为key在$routeParams服务中使用

1
2
3
4
$routeProvider.when('/person/:id', {
  controller: 'PeopleController',
  template: '<div>Person show page: {{ name }}</div>'
})

在PeopleController中,我们检索路由中指定的people的:id

1
2
3
4
5
app.controller('PeopleController', function($scope, $routeParams) {
  // We now have access to the $routeParams
  // At the route /person/42, our $routeParams will look like:
  // { id: 42 }
});

过滤器

在AngularJS的世界里,filter提供了一种格式化数据的方法,Angular也提供给我们了很多内建的过滤器,并且建立自定义过滤器也是相当的简单

在HTML的模板绑定{{}}中,我们使用 | 来调用过滤器,比如,我们想让字符串全部大写字符显示:

1
{{ name | uppercase }}

当然了,我们也可以在JavaScript中使用$filter服务来调用过滤器,还拿字符串大写来举例:

1
2
3
4
5
app.controller('DemoController', ['$scope', '$filter',
  function($scope, $filter) {
 
    $scope.name = $filter('lowercase')('Ari');
}]);

如何传递参数到filter呢?只需要把参数放在filter之后,中间加个冒号(如果有多个参数要传递,在每个参数后加上冒号)比如,数字过滤器可以帮助我们限制数字的位数,如果想显示两位小数,加上number:2就可以了

1
{{ 123.456789 | number:2 }}

See it

123.46

我们可以同时使用N多过滤器,待会我们建立自定义的过滤器的时候就可以看到如何同时使用多个过滤器,在那之前我们继续来看几个Angular自带的过滤器

currency

Currency过滤器主要是把数字格式化成货币,意思就是123格式化以后就成了$123.00

Currency可以根据需要选择适当的货币符号。默认的是根据当前操作系统的locale来转换的

date

日期过滤器主要根据我们提供的格式化形式来格式化日期,他提供了很多内建的选项,如果没有指定格式,默认显示mediumDate形式

下面是一些自带的日期格式化形式,我们可以通过把不同的格式化选项组合使用来创建自定义的日期格式化形式

filter

filter过滤器主要用来过滤一个数组数据并返回一个包含子数组数据的新数组

比如,在客户端搜索时,我们可以快速的从数组中过滤出我们想要的结果

这个filter方法接收一个string,object,或者function参数用来选择/移除数组元素

If the first parameter passed in is a:
String 接收匹配这个字符串的元素,如果想排除某些字符串,在前面加上 ‘!’就行了
Object 如果只传入一个字符串,会作为这个对象的属性名称进行类似substring类似的匹配,如果想匹配所有属性,使用’$’作为键即可
Function 对数组中每个元素执行这个function,执行后得到的结果会放在一个新的数组中

You can also pass a second parameter into the filter method that will be used to determine if the expected value and the actual 你也可以传入第二个参数到filter方法中,他讲用于决定如果期望值和实际值是否考虑匹配的问题

If the second parameter passed in is:
true 执行严格的匹配比较(跟’angular.equals(expected,actual)一样)
false 执行大小写敏感的substring匹配
Function 执行function并接受一个元素,前提是这个function的返回结果是真

See it

isCapitalized函数如下:

1
2
$scope.isCapitalized =
  function(str) { return str[0] == str[0].toUpperCase(); }

json

json 过滤器接收JSON或者JavaScript对象,然后转换成字符串,这个功能在调试程序的时候非常有用!译者感受:妈妈再也不用担心我的debug,方便的令人发指

limitTo

limitTo过滤器会根据传递的参数值来生成新的数组或字符串,参数值为整数,从开头截取,参数为负值,从最后开始截取

如果限定值超过了字符串长度,返回整个数组或字符串

See it

lowercase

lowercase过滤器很明显,将整个字符串编程小写形式

See it

Lowercase string

1
{{ "San Francisco is often cloudy" | lowercase }}   san francisco is often cloudy

number

Number过滤器格式化文本成数字,可以接受参数(可选)来决定格式化后数字的位数

如果参数是非数字,将返回空字符串

See it

简单的数字格式化

1
{{ 1234567890 | number }}  1,234,567,890

格式化数字到一位小数

1
{{ 1.234567 | number:1 }}  1.2

orderBy

orderBy过滤器主要是根据给定的表达式对数组进行排序

orderBy函数可以接受两个参数:第一个是必须要提供的,第二个是可选参数

第一个参数决定了如何对数组进行排序

 如果传进来的第一个参数是:
function 将被用作这个对象的‘getter‘函数
string 字符串会被作为key来对数组元素进行排序,你也可以传进来 ‘+’ 或者‘-‘来决定是升序还是降序
array 使用这个数组里的元素作为排序表达式的判断依据,使用第一个不严格相等表达式的结果的元素作为其他元素的判断依据

The second parameter controls the sort order of the array (either reversed or not).

See it

根据人名排序

uppercase

Uppercase过滤器就是把整个字符串变成大写形式

See it

1
{{ "San Francisco is often cloudy" | uppercase }} SAN FRANCISCO IS OFTEN CLOUDY

创建自定义的过滤器

正如我们前面看到的,创建自定义过滤器相当简单,我们只要把他配置到我们的module下就可以了,让我们一起来创建一个首字母大写的过滤器吧

首先,我们创建一个module

1
2
3
4
angular.module('myApp.filters', [])
.filter('capitalize', function() {
  return function(input) {} 
});

Fliters其实就是一个function,接收input 字符串,我们可以函数里做一些错误检查

1
2
3
4
5
6
7
8
angular.module('myApp.filters', [])
.filter('capitalize', function() {
  return function(input) {
    // input will be ginger in the usage below
    if (input)
      return input[0].toUpperCase() + input.slice(1);
  
});

See it

还有一些话题是我们还没来得及讨论

在这个系列教程中,我们介绍了很多可以让你轻松上手AngularJS的知识点,当然了,还有很多要点没有机会谈到,都列在下面,希望以后有机会跟他家一起研究

  • Promises (可以让多个异步请求更加的有条理)
  • Building custom directives(自定义指令)
  • $resource service($resource 服务,非常好用的一个服务,底层是调用了$http Service)
  • Unit testing(单元测试,这个尤为重要,甚至可以单拿出来讲很多,推荐jasmine)
  • End-to-end testing(同上)
  • Midway testing(介于前面两者的测试)
  • i18n and I10n language translation/localization(多语言)
  • Authentication and customizing XHR requests(验证和自定义XHR请求)
  • Using the $provide service to build customizable services(使用$provider服务来创建自定义服务)
  • Forms and validations(表单和验证)
  • IE compatibility(IE兼容性)

最后呢,如果你们喜欢我们的系列教程,刚好我们正在努力的创作一本书,这本书里论述上面列举的所有话题,更多的信息请访问ng-book.com

这里提供了ng-book的样章,免费的哦!只要留下你的email地址我们就会发送样章到你的收件箱

学习资源列表

关于AngularJS的更多,更深的知识请访问如下站点:

这里是一些有趣的Angular 程序供大家把玩

[学习笔记] 七步从AngularJS菜鸟到专家(7):Routing [转]的更多相关文章

  1. [学习笔记] 七步从AngularJS菜鸟到专家(4和5):指令和表达式 [转]

    这一篇包含了"AngularJS - 七步从菜鸟到专家"系列的第四篇(指令)和第五篇(表达式). 之前的几篇展示了我们应用的核心组件,以及如何设置搭建一个Angular.js应用.在这一部分,我们会厘 ...

  2. [学习笔记] 七步从AngularJS菜鸟到专家(6):服务 [转]

    这是"AngularJS – 七步从菜鸟到专家"系列的第六篇. 在第一篇,我们展示了如何开始搭建一个AngularaJS应用.在第五篇我们讨论了Angular内建的directives.在这一章,我们 ...

  3. 七步从AngularJS菜鸟到专家(7):Routing

    这是"AngularJS – 七步从菜鸟到专家"系列的第七篇. 在第一篇,我们展示了如何開始搭建一个AngularaJS应用.在第四.五篇我们讨论了Angular内建的directives.上一篇了解 ...

  4. [学习笔记] 七步从Angular.JS菜鸟到专家(3):数据绑定和AJAX [转]

    这是"AngularJS - 七步从菜鸟到专家"系列的第三篇. 在第一篇,我们展示了如何开始搭建一个AngularaJS应用.第二篇我们讨论了scope和 $scope 的功能. 通过这整个系列的教程 ...

  5. iOS 学习笔记七 【博爱手把手教你使用2016年gitHub Mac客户端】

    iOS 学习笔记七 [博爱手把手教你使用gitHub客户端] 第一步:首先下载git客户端 链接:https://desktop.github.com 第二步:fork 大神的代码[这里以我的代码为例 ...

  6. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  8. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. suricate学习笔记1--初步认识(转)

    最近在研究关于dpi网卡采集的代码重组这块,公司一个同事,简单的用CPP讲解了suricata内部的一些处理逻辑,,,其中大部分代码是用C语言写的,对于用C重构代码有很好的借鉴作用,,,如果有相关工作 ...

随机推荐

  1. Quartz.NET管理周期性任务

    Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和 ...

  2. Codeforces 723c [贪心][乱搞]

    /* 不要低头,不要放弃,不要气馁,不要慌张. 题意: 给一个n和m. 第二行给n个数. 每次操作可以把n个数中的任何一个数替代为别的数,问最少的操作次数使得1.2.3.4.5...m中的数出现的次数 ...

  3. I2C控制器的Verilog建模之二

    前言:接着上一篇的I2C写操作,今天要实现一个I2C的读操作.虽然在ADV7181B配置内部寄存器时没有必要使用到读操作,但是为了进一步确认寄存器是否在I2C写模块下被正确配置,这一步是必不可少的. ...

  4. MySQL 常用命令(持续更新)

    停止启动MySQL服务 停止:net stop mysql启动:net start mysql 查看正在运行的线程 SHOW PROCESSLIST SHOW FULL PROCESSLIST 杀死线 ...

  5. HTML实体字符转化为HTML标签

    html_entity_decode方法 参数 描述 string 必需.规定要解码的字符串. flags 可选.规定如何处理引号以及使用哪种文档类型. 可用的引号类型: ENT_COMPAT - 默 ...

  6. java并发编程_CountDownLanch(倒计数锁存器)应用场景

    使用介绍: 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown() 方法,所以在 ...

  7. require和include的区别

    require 的使用方法如 require("MyRequireFile.php"); .这个函数通常放在 PHP 程序的最前面,PHP 程序在执行前,就会先读入 require ...

  8. VC++ 在两个程序中 传递字符串等常量值的方法:使用了 WM_COPYDATA 消息的

    消息作用:    在进程间共享数据(内部通过创建内存映射文件) 消息介绍:需要用到的数据结构/类型:typedef struct tagCOPYDATASTRUCT {    ULONG_PTR dw ...

  9. JS出现illegal character非法字符提示

    引用js文件,js文件内的汉字在页面显示乱码 解决方式: a. 保持js文件编码与jsp页面编码格式一致: b. 在引入js文件时,在script中添加charset=""属性,指 ...

  10. JS复习

    一.三个对话框1.alert("")警告对话框2.confirm("")确定对话框3.prompt("","")可输入内 ...