过滤
Controller
没作任何变化
Template
|
|
加个标准的 <input> 标签,使用 Angular 的 $filter 函数为 ngRepeat 指令处理输入内容。
原理说明如下:
数据绑定:Angular 的核心特色之一。页面加载时,Angular 把输入框的名字和数据模型的同名变量绑定,保持两者同步。
用户在输入框输入内容(取名 query),立即作为手机列表的过滤器(phone in phones | filter:query
)过滤器(filter )的使用:filter 函数利用 query 值创建一个匹配
query
结果的新数组。
ngRepeat 自动更新视图,通过过滤器改变手机的数量。实验:
在 index.html 模版增加一个 {{query}} 绑定,可以显示当前的 query 模型的值。
query 模型值出现在 HTML 页面的 title 会是什么情况:
|
|
修改<title> 标签,把 ngController 定义放到 HTML 元素上。确保移除原来 body 上的定义。
ngBind 或 ngBindTemplate 命令,与双大括号等价的写法:
|
|
双向数据绑定
模版增加了下拉菜单:
|
|
添加了 <select> 元素,命名 orderProp。
我们把 orderBy 跟过滤器关联起来,进一步筛选信息。orderBy 把输入信息拷贝,重新排序并返回。
Angular 在 select 元素和 orderProp 模型间建立了双向数据绑定。orderProp 作为输入的 orderBy 过滤器。
当模型改变(例如用户改变了下拉菜单),Angular 的数据绑定促使视图自动更新,并不需要 DOM 操作代码。
Controller
|
|
我们修改了手机数据模型,增加了 age 属性,此属性用于手机排序。
我们增加了一行代码,设置 orderProp 的默认值为 age。如果不定义默认值,直到用户选择了下拉菜单,模型才会初始化。
解释双向绑定
当应用在浏览器加载时,下拉菜单“Newest”选中,因为我们在 controller 设置了 orderProp 为 age,因此模型到 UI 实现了绑定。当你选择“Alphabetically”项时,模型更新,手机也重新排序。此时相反的方向实现了数据绑定 —— 从 UI 到模型。
实验
在 PhoneListCtrl controller 里,移除 orderProp 默认值声明,Angular 向下拉列表临时增加“未知”选项,并且默认顺序是未排序/自然顺序。
在 index.html 模版增加 {{orderProp}} 绑定,可以显示当前的值。
XHR 和依赖注入
刚才的数据源都是硬编码的数据集,让我们用下 angular 的内建服务 $http 从服务器获取大一点的数据集。我们将用 angular 的依赖注入(DI)为 PhoneListCtrl 控制器服务。
数据
项目里的 app/phones/phones.json
文件包含比较大的手机列表。
Controller
我们将在控制器里用 $http 服务向你的 web 服务器发起一个 HTTP 请求,获取 app/phones/phones.json 文件里的数据。$http 仅是 angular 内建服务 的一种,用来处理常见的操作。
该服务被 angular 的 DI 子系统 管理。依赖注入帮助 web app 保持良好结构(比如:独立的组件用于表现,数据和控制),并且松散耦合(组件之间的依赖性不取决于组件本身,而取决于 DI 子系统)。
|
|
$http 向我们服务器发起一个 HTTP GET 请求,请求 phones/phones.json (url 相对于 index.html 文件)。服务器响应提供 json 文件的数据。(响应也有可能被后端服务器动态生成,对浏览器和我们的应用而言,似乎是一样的,此处简单起见用了 json 文件。)
$http 服务返回包含 success 方法的约定对象 。我们调用此方法,处理异步响应,并且把手机数据分配到作用域,作为名叫 phones 的模型。注意到 angular 检测到 json 响应,并解析它。
使用一项服务,只需简单定义依赖的名字,作为控制器的构造函数的参数:
|
|
注意参数的名字只是个象征,因为注入器用它查找相关性。
‘$’ 前缀命名约定
你可以创建自己的服务,实际上 步骤11 这么做了。作为命名约定,angular 内建服务,作用域方法和一些 angular API 会有 ‘$’ 前缀。当命名自己的服务和模型时,为了避免命名冲突,不要使用 ‘$’ 前缀。
注意代码压缩问题
如果你为 PhoneListCtrl 控制器压缩 (http://en.wikipedia.org/wiki/Minification_(programming)) JavaScript 代码,它所有的函数参数也被最小化,依赖注入将无法正确识别服务。
克服最小化代码问题,仅需为 $inject
属性分配一个包含服务标示符的数组,正如(注释)最后一行的代码段:
|
|
另一种解决压缩代码问题的方法,使用方括号:
|
|
实验
在 index.html 底部增加 {{phones | json}} 绑定,看看电话数据 json 格式。
在 PhoneListCtrl 控制器,通过限制手机的数量,预处理 http 响应:
|
|