这是"AngularJS – 七步从菜鸟到专家"系列的第七篇。
在第一篇,我们展示了如何开始搭建一个AngularaJS应用。在第四、五篇我们讨论了Angular内建的directives,上一篇了解了services的强大。
在这一章,我们来看几个前面没有机会细说的关键点,文章的最后会列举一些特别棒的学习资源链接和工具。
通过这整个系列的教程,我们会开发一个NPR(美国全国公共广播电台)广播的音频播放器,它能显示Morning Edition节目里现在播出的最新故事,并在我们的浏览器里播放。完成版的Demo可以看这里。
7. Routing
在单页面应用中,视图之间的跳转就显尤为重要的,随着应用越来越复杂,我们需要用一种方法来精确控制什么时候该呈现怎样的页面给用户。
咱们可以通过在主页面中引入不同的模板来支持不同页面的切换,但是这么做的缺点就是,越来越多的内嵌代码导致最后难以管理。
通过ng-include指令我们可以把很多的模板整合在视图中,但是我们有更好的方法来处理这种情况,我们可以把视图打散成layout和模板视图,然后根据用户访问的特定的URL来显示需要的视图
我们可以将这些“碎片”在一个布局模板中拼接起来
AngularJS通过在$routeProvider($route服务的提供者)上声明routes来实现上面的构想
使用$routeProvider,我们可以更好的利用浏览历史的API并且可以让用户可以把当前路径存成书签以方便以后的使用
在我们的应用中设定路由,我们需要做两件事情:第一,我们需要指出我们存放将要存放新页面内容的布局模板在哪里。比如,如果我们想在所有页面都配上header和footer,我们可以这样设计布局模板:
- <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
- controller: 'MyController'
- // or
- controller: function($scope) {
- // ...
- }
如果在配置对象中设置了controller属性,那这个controller会在route加载的时候实例化,这个属性可以是一个字符串(必须在module中注册过的controller)也可以是controller function
Template模板
- template: '<div><h2>Route</h2></div>'
如果我们在配置对象的template属性设置了值,那么模板就会被渲染到DOM中的ng-view处
templateUrl
- templateUrl: 'views/template_name.html'
如果我们在配置对象的templateUrl属性中设置了值,AngularJS将通过XHR来获取该模板并把模板内容渲染到DOM中的ng-view处
值得注意的是:templateUrl属性跟其他AngularJS XHR请求的处理流程是一样的,也就是说,即使用户从这个页面离开,等他再回到这个页面,应用不会再去请求这个模板页面,因为$templateCache已经缓存了这个模板
添加一些路由
- 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服务中使用
- $routeProvider.when('/person/:id', {
- controller: 'PeopleController',
- template: '<div>Person show page: {{ name }}</div>'
- })
在PeopleController中,我们检索路由中指定的people的:id
- 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 }
- });
#p#
过滤器
在AngularJS的世界里,filter提供了一种格式化数据的方法,Angular也提供给我们了很多内建的过滤器,并且建立自定义过滤器也是相当的简单
在HTML的模板绑定{{}}中,我们使用 | 来调用过滤器,比如,我们想让字符串全部大写字符显示
- {{ name | uppercase }}
当然了,我们也可以在JavaScript中使用$filter服务来调用过滤器,还拿字符串大写来举例:
- app.controller('DemoController', ['$scope', '$filter',
- function($scope, $filter) {
- $scope.name = $filter('lowercase')('Ari');
- }]);
如何传递参数到filter呢?只需要把参数放在filter之后,中间加个冒号(如果有多个参数要传递,在每个参数后加上冒号)比如,数字过滤器可以帮助我们限制数字的位数,如果想显示两位小数,加上number:2就可以了
- {{ 123.456789 | number:2 }}
See it
123.46
我们可以同时使用N多过滤器,待会我们建立自定义的过滤器的时候就可以看到如何同时使用多个过滤器,在那之前我们继续来看几个Angular自带的过滤器
currency
Currency过滤器主要是把数字格式化成货币,意思就是123格式化以后就成了$123.00
Currency可以根据需要选择适当的货币符号。默认的是根据当前操作系统的locale来转换的
date
日期过滤器主要根据我们提供的格式化形式来格式化日期,他提供了很多内建的选项,如果没有指定格式,默认显示mediumDate形式
下面是一些自带的日期格式化形式,我们可以通过把不同的格式化选项组合使用来创建自定义的日期格式化形式
#p#
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函数如下:
- $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
- {{ "San Francisco is often cloudy" | lowercase }} san francisco is often cloudy
number
Number过滤器格式化文本成数字,可以接受参数(可选)来决定格式化后数字的位数
如果参数是非数字,将返回空字符串
See it
简单的数字格式化
- {{ 1234567890 | number }} 1,234,567,890
格式化数字到一位小数
- {{ 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
- {{ "San Francisco is often cloudy" | uppercase }} SAN FRANCISCO IS OFTEN CLOUDY
#p#
创建自定义的过滤器
正如我们前面看到的,创建自定义过滤器相当简单,我们只要把他配置到我们的module下就可以了,让我们一起来创建一个首字母大写的过滤器吧
首先,我们创建一个module
- angular.module('myApp.filters', [])
- .filter('capitalize', function() {
- return function(input) {}
- });
Fliters其实就是一个function,接收input 字符串,我们可以函数里做一些错误检查
- 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兼容性)
原文链接:http://blog.jobbole.com/50533/