### 7.5. 表单控件
表单控件类的模板指令,最大的作用是它预定义了需要绑定的数据的格式。这样,就可以对于既定的数据进行既定的处理。
### 7.5.1. form
_form_ 是核心的一个控件。 ng 对 _form_ 这个标签作了包装。事实上, ng 自己的指令是叫 _ng-form_ 的,区别在于, _form_ 标签不能嵌套,而使用 _ng-form_ 指令就可以做嵌套的表单了。
_form_ 的行为中依赖它里面的各个输入控制的状态的,在这里,我们主要关心的是 _form_ 自己的一些方法和属性。从 ng 的角度来说, _form_ 标签,是一个模板指令,也创建了一个 _FormController_ 的实例。这个实例就提供了相应的属性和方法。同时,它里面的控件也是一个 _NgModelController_ 实例。
很重要的一点, _form_ 的相关方法要生效,必须为 _form_ 标签指定 _name_ 和 _ng-controller_ ,并且每个控件都要绑定一个变量。 _form_ 和控件的名字,即是 _$scope_ 中的相关实例的引用变量名。
<form name="test_form" ng-controller="TestCtrl">
<input type="text" name="a" required ng-model="a" />
<span ng-click="see()">{{ test_form.$valid }}</span>
</form>
var TestCtrl = function($scope){
$scope.see = function(){
console.log($scope.test_form);
console.log($scope.test_form.a);
}
}
除去对象的方法与属性, _form_ 这个标签本身有一些动态类可以使用:
- _ng-valid_ 当表单验证通过时的设置
- _ng-invalid_ 当表单验证失败时的设置
- _ng-pristine_ 表单的未被动之前拥有
- _ng-dirty_ 表单被动过之后拥有
_form_ 对象的属性有:
- _$pristine_ 表单是否未被动过
- _$dirty_ 表单是否被动过
- _$valid_ 表单是否验证通过
- _$invalid_ 表单是否验证失败
- _$error_ 表单的验证错误
其中的 _$error_ 对象包含有所有字段的验证信息,及对相关字段的 _NgModelController_ 实例的引用。它的结构是一个对象, `key` 是失败信息, _required_ , _minlength_ 之类的, `value` 是对应的字段实例列表。
注意,这里的失败信息是按序列取的一个。比如,如果一个字段既要求 _required_ ,也要求 _minlength_ ,那么当它为空时, _$error_ 中只有 _required_ 的失败信息。只输入一个字符之后, _required_ 条件满足了,才可能有 _minlength_ 这个失败信息。
<form name="test_form" ng-controller="TestCtrl">
<input type="text" name="a" required ng-model="a" />
<input type="text" name="b" required ng-model="b" ng-minlength="2" />
<span ng-click="see()">{{ test_form.$error }}</span>
</form>
var TestCtrl = function($scope){
$scope.see = function(){
console.log($scope.test_form.$error);
}
}
### 7.5.2. input
_input_ 是数据的最主要入口。 ng 支持 HTML5 中的相关属性,同时对旧浏览器也做了兼容性处理。最重要的, _input_ 的规则定义,是所属表单的相关行为的参照(比如表单是否验证成功)。
_input_ 控件的相关可用属性为:
- _name_ 名字
- _ng-model_ 绑定的数据
- _required_ 是否必填
- _ng-required_ 是否必填
- _ng-minlength_ 最小长度
- _ng-maxlength_ 最大长度
- _ng-pattern_ 匹配模式
- _ng-change_ 值变化时的回调
<form name="test_form" ng-controller="TestCtrl">
<input type="text" name="a" ng-model="a" required ng-pattern="/abc/" />
<span ng-click="see()">{{ test_form.$error }}</span>
</form>
_input_ 控件,它还有一些扩展,这些扩展有些有自己的属性:
- _input type="number"_ 多了 `number` 错误类型,多了 _max_ , _min_ 属性。
- _input type="url"_ 多了 `url` 错误类型。
- _input type="email"_ 多了 `email` 错误类型。
### 7.5.3. checkbox
它也算是 _input_ 的扩展,不过,它没有验证相关的东西,只有选中与不选中两个值:
<form name="test_form" ng-controller="TestCtrl">
<input type="checkbox" name="a" ng-model="a" ng-true-value="AA" ng-false-value="BB" />
<span>{{ a }}</span>
</form>
var TestCtrl = function($scope){
$scope.a = 'AA';
}
两点:
1. controller 要初始化变量值。
1. controller 中的初始化值会关系到控件状态(双向绑定)。
### 7.5.4. radio
也是 _input_ 的扩展。和 _checkbox_ 一样,但它只有一个值了:
<form name="test_form" ng-controller="TestCtrl">
<input type="radio" name="a" ng-model="a" value="AA" />
<input type="radio" name="a" ng-model="a" value="BB" />
<span>{{ a }}</span>
</form>
### 7.5.5. textarea
同 _input_ 。
### 7.5.6. select
这是一个比较牛B的控件。它里面的一个叫做 _ng-options_ 的属性用于数据呈现。
对于给定列表时的使用。
最简单的使用方法, `x for x in list` :
<form name="test_form" ng-controller="TestCtrl" ng-init="o=[0,1,2,3]; a=o[1];">
<select ng-model="a" ng-options="x for x in o" ng-change="show()">
<option value="">可以加这个空值</option>
</select>
</form>
<script type="text/javascript">
var TestCtrl = function($scope){
$scope.show = function(){
console.log($scope.a);
}
}
angular.bootstrap(document.documentElement);
</script>
在 _$scope_ 中, _select_ 绑定的变量,其值和普通的 _value_ 无关,可以是一个对象:
<form name="test_form" ng-controller="TestCtrl"
ng-init="o=[{name: 'AA'}, {name: 'BB'}]; a=o[1];">
<select ng-model="a" ng-options="x.name for x in o" ng-change="show()">
</select>
</form>
显示与值分别指定, `x.v as x.name for x in o` :
<form name="test_form" ng-controller="TestCtrl"
ng-init="o=[{name: 'AA', v: '00'}, {name: 'BB', v: '11'}]; a=o[1].v;">
<select ng-model="a" ng-options="x.v as x.name for x in o" ng-change="show()">
</select>
</form>
加入分组的, `x.name group by x.g for x in o` :
<form name="test_form" ng-controller="TestCtrl"
ng-init="o=[{name: 'AA', g: '00'}, {name: 'BB', g: '11'}, {name: 'CC', g: '00'}]; a=o[1];">
<select ng-model="a" ng-options="x.name group by x.g for x in o" ng-change="show()">
</select>
</form>
分组了还分别指定显示与值的, `x.v as x.name group by x.g for x in o` :
<form name="test_form" ng-controller="TestCtrl" ng-init="o=[{name: 'AA', g: '00', v: '='}, {name: 'BB', g: '11', v: '+'}, {name: 'CC', g: '00', v: '!'}]; a=o[1].v;">
<select ng-model="a" ng-options="x.v as x.name group by x.g for x in o" ng-change="show()">
</select>
</form>
如果参数是对象的话,基本也是一样的,只是把遍历的对象改成 `(key, value)` :
<form name="test_form" ng-controller="TestCtrl" ng-init="o={a: 0, b: 1}; a=o.a;">
<select ng-model="a" ng-options="k for (k, v) in o" ng-change="show()">
</select>
</form>
<form name="test_form" ng-controller="TestCtrl"
ng-init="o={a: {name: 'AA', v: '00'}, b: {name: 'BB', v: '11'}}; a=o.a.v;">
<select ng-model="a" ng-options="v.v as v.name for (k, v) in o" ng-change="show()">
</select>
</form>
<form name="test_form" ng-controller="TestCtrl"
ng-init="o={a: {name: 'AA', v: '00', g: '=='}, b: {name: 'BB', v: '11', g: '=='}}; a=o.a;">
<select ng-model="a" ng-options="v.name group by v.g for (k, v) in o" ng-change="show()">
</select>
</form>
<form name="test_form" ng-controller="TestCtrl"
ng-init="o={a: {name: 'AA', v: '00', g: '=='}, b: {name: 'BB', v: '11', g: '=='}}; a=o.a.v;">
<select ng-model="a" ng-options="v.v as v.name group by v.g for (k, v) in o" ng-change="show()">
</select>
</form>
- Introduction
- 关于AngularJS
- 关于本文档
- 开始的例子
- 依赖注入
- 作用域
- 数据绑定与模板
- 数据->模板
- 模板->数据
- 数据->模板->数据->模板
- 模板
- 定义模板内容
- 内容渲染控制
- 节点控制
- 事件绑定
- 表单控件
- 模板中的过滤器
- 排序 orderBy
- 过滤列表 filter
- 其它
- 例子:表头排序
- 例子:搜索
- 锚点路由
- 路由定义
- 参数定义
- 业务处理
- 定义模板变量标识标签
- AJAX
- HTTP请求
- 广义回调管理
- 工具函数
- 上下文绑定
- 对象处理
- 类型判定
- 其它服务
- 日志
- 缓存
- 计时器
- 表达式函数化
- 模板单独使用
- 自定义模块和服务
- 模块和服务的概念与关系
- 定义模块
- 定义服务
- 引入模块并使用服务
- 附加模块 ngResource
- 使用引入与整体概念
- 基本定义
- 基本使用
- 定义和使用时的占位量
- 实例
- AngularJS与其它框架的混用(jQuery, Dojo)
- 自定义过滤器
- 自定义指令directive
- 指令的使用
- 指令的执行过程
- 基本的自定义方法
- 属性值类型的自定义
- Compile的细节
- transclude的细节
- 把节点内容作为变量处理的类型
- 指令定义时的参数
- Attributes的细节
- 预定义的 NgModelController
- 预定义的 FormController
- 示例:文本框
- 示例:模板控制语句 for
- 示例:模板控制语句 if/else