Angular表单其实是Angular提供的Directive,它有一个别名叫ng-form
。是这个Directive实例化了一个FormController
来负责表单内的页面逻辑(主要是表单验证)。
<div ng-app>
<ng-form name=someForm>
<input name="username" type="text" ng-model="user.username" pattern="^\w{6,18}$">
<div class="alert alert-danger" ng-show="someForm.username.$error.pattern">
用户名必须为6-18个字母、数字或下划线
</div>
</ng-form>
</div>
ng-model
可以把input
的值双向地绑定到当前上下文的user.username
变量。我们设置了用户名的pattern
为6到18位。我们输入用户名时,.alert
错误提示便会实时地显示或者隐藏。
这里我们指定了
form
的name
属性,form
Directive 实例化的FormController
就会以someForm
命名,并插入到当前$scope
。所以在模板中才能够访问userForm
变量。另外,Angular的Pattern使用Javascript正则表达式语法,这里\w
相当于[a-zA-Z_]
。
select标签
html中的select标签是一个单选的下下拉列表,angular对select也提供了支持(事实上,是在ng module里面提供了一个叫select的directive)假如上下文中有这样的对象:
$scope.selectValue=[{value:0,label:'Banana'},{value:1,label:'apple'}];
$scope.selectedValue = 1;
在模板中这样写:
<select ng-model="selectedValue" ng-options="option.value as option.label for option in myOptions"></select>
这个select的便会有两个选项:banana和apple,且默认选中banana,当你选择apple时,$scope.selectedValue会被赋值为1,option.value指定了select下option的value,而option.label指定了option的内容。
事实上,因为select下拉项的样式不可通过css控制,select在追求视觉体验的网站不常用。bootstrap的.dropdown就是一个更好的替代品
表单嵌套
多数浏览器不允许form嵌套,如果你出于自身的需求,例如在账号表单中,头像表单需要单独提交小嵌套的表单,请使用ng-form标签:
<ng-form name="outterForm">
<ng-form name="innerForm" ng-repeat="file in doc.files">
... <button ng-disabled="innerForm.$invalid">save inner</button>
</ng-form>
<button ng-disabled="outterForm.$invalid || innerForm.$invalid">save outter</button>
</ng-form>
这里的outterForm下有一个动态的innerForm列表,在innerForm下的元素$scope中时当前列表项的innerForm.因此saveInner的状态会根据正确的绑定到当前表单的状态
在outterForm下的save outter则会同时绑定outterForm和innerForm的状态,当所有的InnerForm合法且outterFrom合法时,按钮被激活。
渐进呈现
在页面载入时,由于angular的控制器仍为完成构造过程,表单会短暂地显示为原始的html。
当然你能想到的最直接的解决方案是给表单加一个隐藏的样式,在载入后去掉它。然而angular已经提供ngCloak directive来完成这件事情,我们只需要在表单上加一个ng-cloak
<form ng-cloak></form>
ng-cloak可以直接加在body上,但在载入过程中,整个body都会隐藏。这与html的渐进呈现的原则是相悖的。建议在表单上单独的应用ng-cloak