AngularJS入门教程之迭代器过滤详解


Posted in Javascript onAugust 18, 2016

我们在上一步做了很多基础性的训练,所以现在我们可以来做一些简单的事情喽。我们要加入全文检索功能(没错,这个真的非常简单!)。同时,我们也会写一个端到端测试,因为一个好的端到端测试可以帮上很大忙。它监视着你的应用,并且在发生回归的时候迅速报告。

请重置工作目录:

git checkout -f step-3

我们的应用现在有了一个搜索框。注意到页面上的手机列表随着用户在搜索框中的输入而变化。

步骤2和步骤3之间最重要的不同在下面列出。你可以在GitHub里看到完整的差别。

控制器

我们对控制器不做任何修改。

模板

app/index.html

<div class="container-fluid">
 <div class="row-fluid">
  <div class="span2">
   <!--Sidebar content-->

   Search: <input ng-model="query">

  </div>
  <div class="span10">
   <!--Body content-->

   <ul class="phones">
    <li ng-repeat="phone in phones | filter:query">
     {{phone.name}}
    <p>{{phone.snippet}}</p>
    </li>
   </ul>

    </div>
 </div>
</div>

我们现在添加了一个<input>标签,并且使用AngularJS的$filter函数来处理ngRepeat指令的输入。

这样允许用户输入一个搜索条件,立刻就能看到对电话列表的搜索结果。我们来解释一下新的代码:

数据绑定: 这是AngularJS的一个核心特性。当页面加载的时候,AngularJS会根据输入框的属性值名字,将其与数据模型中相同名字的变量绑定在一起,以确保两者的同步性。

在这段代码中,用户在输入框中输入的数据名字称作query,会立刻作为列表迭代器(phone in phones | filter:query`)其过滤器的输入。当数据模型引起迭代器输入变化的时候,迭代器可以高效得更新DOM将数据模型最新的状态反映出来。

AngularJS入门教程之迭代器过滤详解

使用filter过滤器:filter函数使用query的值来创建一个只包含匹配query记录的新数组。

ngRepeat会根据filter过滤器生成的手机记录数据数组来自动更新视图。整个过程对于开发者来说都是透明的。

测试

在步骤2,我们学习了编写和运行一个测试的方法。单元测试用来测试我们用js编写的控制器和其他组件都非常方便,但是不能方便的对DOM操作和应用集成进行测试。对于这些来说,端到端测试是一个更好的选择。

搜索特性是完全通过模板和数据绑定实现的,所以我们的第一个端到端测试就来验证这些特性是否符合我们的预期。

test/e2e/scenarios.js:

describe('PhoneCat App', function() {

 describe('Phone list view', function() {

  beforeEach(function() {
   browser().navigateTo('../../app/index.html');
  });


  it('should filter the phone list as user types into the search box', function() {
   expect(repeater('.phones li').count()).toBe(3);

   input('query').enter('nexus');
   expect(repeater('.phones li').count()).toBe(1);

   input('query').enter('motorola');
   expect(repeater('.phones li').count()).toBe(2);
  });
 });
});

尽管这段测试代码的语法看起来和我们之前用Jasmine写的单元测试非常像,但是端到端测试使用的是AngularJS端到端测试器提供的接口。

运行一个端到端测试,在浏览器新标签页中打开下面任意一个:

node.js用户:http://localhost:8000/test/e2e/runner.html

使用其他http服务器的用户:http://localhost:[port-number]/[context-path]/test/e2e/runner.html

访客:http://angular.github.com/angular-phonecat/step-3/test/e2e/runner.html

这个测试验证了搜素框和迭代器被正确地集成起来。你可以发现,在AngularJS里写一个端到端测试多么的简单。尽管这个例子仅仅是一个简单的测试,但是用它来构建任何一个复杂、可读的端到端测试都很容易。

练习

在index.html模板中添加一个{{query}}绑定来实时显示query模型的当前值,然后观察他们是如何根据输入框中的值而变化。
现在我们来看一下我们怎么让query模型的值出现在HTML的页面标题上。

你或许认为像下面这样在title标签上加上一个绑定就行了:

<title>Google Phone Gallery: {{query}}</title>

但是,当你重载页面的时候,你根本没办法得到期望的结果。这是因为query模型仅仅在body元素定义的作用域内才有效。

<body ng-controller="PhoneListCtrl">

如果你想让<title>元素绑定上query模型,你必须把ngController声明移动到HTML元素上,因为它是title和body元素的共同祖先。

<html ng-app ng-controller="PhoneListCtrl">

一定要注意把body元素上的ng-controller声明给删了。

当绑定两个花括号在title元素上可以实现我们的目标,但是你或许发现了,页面正加载的时候它们已经显示给用户看了。一个更好的解决方案是使用ngBind或者ngBindTemplate指令,它们在页面加载时对用户是不可见的:

<title ng-bind-template="Google Phone Gallery: {{query}}">Google Phone Gallery</title>

在test/e2e/scenarios.js的describe块中加入下面这些端到端测试代码:

it('should display the current filter value within an element with id "status"',
  function() {
    expect(element('#status').text()).toMatch(/Current filter: \s*$/);
    input('query').enter('nexus');
    expect(element('#status').text()).toMatch(/Current filter: nexus\s*$/);
    //alternative version of the last assertion that tests just the value of the binding
    using('#status').expect(binding('query')).toBe('nexus');
});

刷新浏览器,端到端测试器会报告测试失败。为了让测试通过,编辑index.html,添加一个id为“status”的div或者p元素,内容是一个query绑定,再加上Current filter:前缀。例如:

<div id="status">Current filter: {{query}}</div>

在端到端测试里面加一条pause();语句,重新跑一遍。你将发现测试器暂停了!这样允许你有机会在测试运行过程中查看你应用的状态。测试应用是实时的!你可以更换搜索内容来证明。稍有经验你就会知道,这对于在端到端测试中迅速找到问题是多么的关键。

总结

我们现在添加了全文搜索功能,并且完成一个测试证明了搜索是对的!现在让我们继续到步骤4来看看给我们的手机应用增加排序功能。

以上就是对AngularJS 迭代器过滤资料整理,后续继续补充相关资料,谢谢大家对本站的支持!

Javascript 相关文章推荐
解决 firefox 不支持 document.all的方法
Mar 12 Javascript
简单的js分页脚本
May 21 Javascript
ie focus bug 解决方法
Sep 03 Javascript
javascript 数据类型转换(parseInt,parseFloat)
Jul 20 Javascript
jQuery+.net实现浏览更多内容(改编php版本)
Mar 28 Javascript
你未必知道的JavaScript和CSS交互的5种方法
Apr 02 Javascript
在ASP.NET MVC项目中使用RequireJS库的用法示例
Feb 15 Javascript
JavaScript开发Chrome浏览器扩展程序UI的教程
May 16 Javascript
Vue组件之自定义事件的功能图解
Feb 01 Javascript
解决koa2 ctx.render is not a function报错问题
Aug 07 Javascript
JS插入排序简单理解与实现方法分析
Nov 25 Javascript
vue 对axios get pust put delete封装的实例代码
Jan 05 Javascript
AngularJS入门教程之AngularJS 模板
Aug 18 #Javascript
AngularJS入门教程之静态模板详解
Aug 18 #Javascript
AngularJS入门教程引导程序
Aug 18 #Javascript
Bootstrap模态框(modal)垂直居中的实例代码
Aug 18 #Javascript
js 获取站点应用名的简单实例
Aug 18 #Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
Aug 18 #Javascript
js修改onclick动作的四种方法(推荐)
Aug 18 #Javascript
You might like
PHP无限分类的类
2007/01/02 PHP
YII分模块加载路由的实现方法
2018/10/01 PHP
jquery 的 $(&quot;#id&quot;).html() 无内容的解决方法
2010/06/07 Javascript
JavaScript在多浏览器下for循环的使用方法
2012/11/07 Javascript
基于PHP和Mysql相结合使用jqGrid读取数据并显示
2015/12/02 Javascript
用jmSlip编写移动端顶部日历选择控件
2016/10/24 Javascript
JS组件系列之MVVM组件构建自己的Vue组件
2017/04/28 Javascript
微信小程序开发之toast提示插件使用示例
2017/06/08 Javascript
js实现图片懒加载效果
2017/07/17 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
2017/08/22 Javascript
利用three.js画一个3D立体的正方体示例代码
2017/11/19 Javascript
jQuery子选择器与可见性选择器实例分析
2019/06/28 jQuery
Vue toFixed保留两位小数的3种方式
2020/10/23 Javascript
vue 使用class创建和清除水印的示例代码
2020/12/25 Vue.js
Python常用的内置序列结构(列表、元组、字典)学习笔记
2016/07/08 Python
python+requests+unittest API接口测试实例(详解)
2017/06/10 Python
python 列表删除所有指定元素的方法
2018/04/19 Python
详解Python 解压缩文件
2019/04/09 Python
DataFrame.groupby()所见的各种用法详解
2020/06/14 Python
利用Vscode进行Python开发环境配置的步骤
2020/06/22 Python
python 装饰器重要在哪
2021/02/14 Python
MUGLER官方网站:蒂埃里·穆勒香水
2019/11/26 全球购物
娇韵诗Clarins意大利官方网站:法国天然护肤品牌
2020/03/11 全球购物
一些网络技术方面的面试题
2014/05/01 面试题
求职简历自荐信范文
2013/10/21 职场文书
教师自荐信
2013/12/10 职场文书
机械制造专业个人的自我评价
2013/12/28 职场文书
商铺租赁意向书
2014/04/01 职场文书
大学学生会竞选演讲稿
2014/04/25 职场文书
2014年安全工作总结范文
2014/11/13 职场文书
家庭财产分割协议书范本
2014/11/24 职场文书
2014年建筑工程工作总结
2014/12/03 职场文书
2014年小学辅导员工作总结
2014/12/23 职场文书
毕业欢送晚会主持词
2019/06/25 职场文书
面试被问select......for update会锁表还是锁行
2021/11/11 MySQL
python中字符串String及其常见操作指南(方法、函数)
2022/04/06 Python