AngularJS 表单
·
AngularJS 表单学习笔记(详细版)
一、AngularJS 表单核心概念
AngularJS 对 HTML 表单进行了深度扩展,提供了双向数据绑定、表单验证、状态追踪等能力。表单在 AngularJS 中是一等公民。
1.1 核心特性
| 特性 | 说明 |
|---|---|
| 双向数据绑定 | ng-model 将表单控件与模型自动同步 |
| 表单状态追踪 | 自动追踪 pristine/dirty/valid/invalid 等状态 |
| 内置验证 | required、minlength、maxlength、pattern 等 |
| 自定义验证 | 通过指令实现复杂验证逻辑 |
| CSS 类自动添加 | 根据状态自动添加 CSS 类,方便样式控制 |
二、基础用法:ng-model
ng-model 是 AngularJS 表单的核心指令,实现视图 ↔ 模型的双向绑定。
2.1 基本绑定
<form ng-app="myApp" ng-controller="FormController">
<input type="text" ng-model="user.name" placeholder="姓名">
<input type="email" ng-model="user.email" placeholder="邮箱">
<p>你好,{{ user.name }}!邮箱:{{ user.email }}</p>
</form>
angular.module('myApp', [])
.controller('FormController', ['$scope', function($scope) {
$scope.user = {
name: '',
email: ''
};
}]);
2.2 ng-model 支持的表单元素
| 元素 | 示例 |
|---|---|
<input type="text"> |
ng-model="user.name" |
<input type="email"> |
ng-model="user.email" |
<input type="number"> |
ng-model="user.age" |
<input type="checkbox"> |
ng-model="user.agree" |
<input type="radio"> |
ng-model="user.gender" |
<select> |
ng-model="user.city" |
<textarea> |
ng-model="user.bio" |
2.3 各类型详细示例
<!-- 文本输入 -->
<input type="text" ng-model="user.name">
<!-- 邮箱 -->
<input type="email" ng-model="user.email">
<!-- 数字 -->
<input type="number" ng-model="user.age" min="0" max="150">
<!-- 复选框 -->
<input type="checkbox" ng-model="user.agree"> 同意条款
<!-- 单选按钮 -->
<input type="radio" ng-model="user.gender" value="male"> 男
<input type="radio" ng-model="user.gender" value="female"> 女
<!-- 下拉选择 -->
<select ng-model="user.city">
<option value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select>
<!-- 多行文本 -->
<textarea ng-model="user.bio" rows="4"></textarea>
三、表单与控件命名规则
AngularJS 会根据 name 属性将表单和控件注册到 $scope 上:
<form name="myForm" ng-app="myApp" ng-controller="FormController">
<input name="userName" type="text" ng-model="user.name" required>
<!-- myForm.userName 可访问该输入框的状态 -->
</form>
关键规则:
- 表单的
name属性 → 注册为$scope.myForm - 控件的
name属性 → 注册为$scope.myForm.userName - 没有
name属性的控件不会被追踪
四、表单状态追踪
4.1 表单级别状态
| 属性 | 类型 | 说明 |
|---|---|---|
myForm.$pristine |
boolean | 表单是否未被修改过(原始状态) |
myForm.$dirty |
boolean | 表单是否已被修改过 |
myForm.$valid |
boolean | 表单是否全部验证通过 |
myForm.$invalid |
boolean | 表单是否存在验证失败 |
myForm.$submitted |
boolean | 表单是否已提交 |
myForm.$error |
object | 验证错误详情(按验证类型分组) |
4.2 控件级别状态
| 属性 | 类型 | 说明 |
|---|---|---|
myForm.userName.$pristine |
boolean | 该控件是否未被修改 |
myForm.userName.$dirty |
boolean | 该控件是否已被修改 |
myForm.userName.$valid |
boolean | 该控件验证是否通过 |
myForm.userName.$invalid |
boolean | 该控件验证是否失败 |
myForm.userName.$touched |
boolean | 该控件是否失去过焦点 |
myForm.userName.$untouched |
boolean | 该控件是否从未失去焦点 |
myForm.userName.$error |
object | 该控件的验证错误详情 |
4.3 状态流转图
修改内容
$pristine ──────────────► $dirty
(原始) (已修改)
│ │
│ 失去焦点 │ 失去焦点
▼ ▼
$untouched ────────────► $touched
(未触碰) (已触碰)
$valid ◄──── 验证通过/失败 ────► $invalid
4.4 状态展示示例
<form name="userForm" ng-controller="FormController">
<input name="name" type="text" ng-model="user.name" required>
<div>
<p>表单状态:</p>
<ul>
<li>$pristine: {{ userForm.$pristine }}</li>
<li>$dirty: {{ userForm.$dirty }}</li>
<li>$valid: {{ userForm.$valid }}</li>
<li>$invalid: {{ userForm.$invalid }}</li>
<li>$submitted: {{ userForm.$submitted }}</li>
</ul>
</div>
<div>
<p>name 控件状态:</p>
<ul>
<li>$pristine: {{ userForm.name.$pristine }}</li>
<li>$dirty: {{ userForm.name.$dirty }}</li>
<li>$valid: {{ userForm.name.$valid }}</li>
<li>$invalid: {{ userForm.name.$invalid }}</li>
<li>$touched: {{ userForm.name.$touched }}</li>
<li>$error: {{ userForm.name.$error | json }}</li>
</ul>
</div>
</form>
五、自动 CSS 类
AngularJS 根据控件状态自动添加/移除 CSS 类,无需手动操作 DOM:
| CSS 类 | 添加时机 |
|---|---|
ng-pristine |
控件未被修改 |
ng-dirty |
控件已被修改 |
ng-valid |
验证通过 |
ng-invalid |
验证失败 |
ng-touched |
控件失去过焦点 |
ng-untouched |
控件未失去过焦点 |
ng-valid-[key] |
特定验证通过(如 ng-valid-required) |
ng-invalid-[key] |
特定验证失败(如 ng-invalid-required) |
5.1 利用 CSS 类美化表单
/* 原始状态 —— 灰色边框 */
input.ng-pristine {
border: 2px solid #ccc;
}
/* 修改过且有效 —— 绿色边框 */
input.ng-dirty.ng-valid {
border: 2px solid #4caf50;
}
/* 修改过且无效 —— 红色边框 */
input.ng-dirty.ng-invalid {
border: 2px solid #f44336;
}
/* 未修改时不要显示错误样式 */
input.ng-pristine.ng-invalid {
border: 2px solid #ccc;
}
六、内置验证指令
6.1 验证指令一览
| 指令/属性 | 适用类型 | 说明 |
|---|---|---|
required |
所有 | 必填 |
ng-required |
所有 | 动态必填(表达式) |
minlength |
text/number | 最小长度 |
ng-minlength |
text/number | 动态最小长度 |
maxlength |
text/number | 最大长度 |
ng-maxlength |
text/number | 动态最大长度 |
min |
number/date | 最小值 |
max |
number/date | 最大值 |
pattern |
text | 正则匹配 |
ng-pattern |
text | 动态正则匹配 |
type="email" |
input | 邮箱格式验证 |
type="url" |
input | URL 格式验证 |
type="number" |
input | 数字验证 |
6.2 完整验证示例
<form name="regForm" ng-controller="RegController" novalidate>
<!-- novalidate 禁用浏览器原生验证,使用 AngularJS 验证 -->
<!-- 用户名:必填 + 长度限制 -->
<div>
<label>用户名</label>
<input type="text"
name="username"
ng-model="user.username"
required
ng-minlength="3"
ng-maxlength="20">
<span ng-show="regForm.username.$dirty && regForm.username.$error.required">
用户名必填
</span>
<span ng-show="regForm.username.$dirty && regForm.username.$error.minlength">
用户名至少3个字符
</span>
<span ng-show="regForm.username.$dirty && regForm.username.$error.maxlength">
用户名最多20个字符
</span>
</div>
<!-- 邮箱:必填 + 邮箱格式 -->
<div>
<label>邮箱</label>
<input type="email"
name="email"
ng-model="user.email"
required>
<span ng-show="regForm.email.$dirty && regForm.email.$error.required">
邮箱必填
</span>
<span ng-show="regForm.email.$dirty && regForm.email.$error.email">
邮箱格式不正确
</span>
</div>
<!-- 年龄:必填 + 范围 -->
<div>
<label>年龄</label>
<input type="number"
name="age"
ng-model="user.age"
required
min="1"
max="150">
<span ng-show="regForm.age.$dirty && regForm.age.$error.required">
年龄必填
</span>
<span ng-show="regForm.age.$dirty && regForm.age.$error.min">
年龄不能小于1
</span>
<span ng-show="regForm.age.$dirty && regForm.age.$error.max">
年龄不能大于150
</span>
</div>
<!-- 密码:必填 + 正则 -->
<div>
<label>密码</label>
<input type="password"
name="password"
ng-model="user.password"
required
ng-pattern="/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/">
<span ng-show="regForm.password.$dirty && regForm.password.$error.required">
密码必填
</span>
<span ng-show="regForm.password.$dirty && regForm.password.$error.pattern">
密码至少8位,需包含字母和数字
</span>
</div>
<!-- 提交按钮 -->
<button type="submit"
ng-disabled="regForm.$invalid"
ng-click="submit()">
注册
</button>
</form>
angular.module('myApp', [])
.controller('RegController', ['$scope', function($scope) {
$scope.user = {};
$scope.submit = function() {
if ($scope.regForm.$valid) {
console.log('提交数据:', $scope.user);
// 发送到后端...
}
};
}]);
七、$error 对象详解
$error 是一个按验证类型分组的对象,是表单验证的核心查询接口。
7.1 控件级别 $error
// regForm.username.$error 的结构
{
required: true, // 未填写
minlength: true, // 长度不足
maxlength: false, // 长度未超限
pattern: false // 正则匹配通过
}
7.2 表单级别 $error
// regForm.$error 的结构 —— 按验证类型分组,值为控件数组
{
required: [regForm.username, regForm.email],
email: [regForm.email],
minlength: [regForm.username]
}
7.3 利用 $error 做全局错误提示
<div ng-show="regForm.$submitted && regForm.$invalid">
<p>表单存在以下错误:</p>
<ul>
<li ng-repeat="(key, value) in regForm.$error">
{{ key }}: {{ value.length }} 个字段未通过
</li>
</ul>
</div>
八、ngMessages 模块(推荐)
ngMessages 是 AngularJS 1.3+ 引入的模块,用于优雅地管理验证消息,替代繁琐的 ng-show 判断。
8.1 引入 ngMessages
<script src="angular.js"></script>
<script src="angular-messages.js"></script>
angular.module('myApp', ['ngMessages']);
8.2 基本用法
<form name="myForm" ng-controller="MyController" novalidate>
<div>
<label>邮箱</label>
<input type="email"
name="email"
ng-model="user.email"
required>
<!-- 使用 ng-messages -->
<div ng-messages="myForm.email.$error" ng-if="myForm.email.$dirty">
<div ng-message="required">邮箱必填</div>
<div ng-message="email">邮箱格式不正确</div>
</div>
</div>
</form>
优势:
- 代码更简洁,无需大量
ng-show - 默认只显示第一条错误消息(避免信息过载)
- 可通过
ng-messages-multiple显示所有错误
8.3 显示多条错误
<div ng-messages="myForm.email.$error"
ng-if="myForm.email.$dirty"
ng-messages-multiple>
<div ng-message="required">邮箱必填</div>
<div ng-message="email">邮箱格式不正确</div>
</div>
8.4 复用错误消息模板
<!-- 定义模板 -->
<script type="text/ng-template" id="error-messages">
<div ng-message="required">此字段必填</div>
<div ng-message="minlength">输入太短</div>
<div ng-message="maxlength">输入太长</div>
<div ng-message="email">邮箱格式不正确</div>
<div ng-message="pattern">格式不符合要求</div>
<div ng-message="min">值太小</div>
<div ng-message="max">值太大</div>
</script>
<!-- 使用模板 -->
<div ng-messages="myForm.username.$error"
ng-if="myForm.username.$dirty"
ng-messages-include="error-messages">
</div>
<!-- 也可以在引用模板后追加自定义消息 -->
<div ng-messages="myForm.password.$error"
ng-if="myForm.password.$dirty"
ng-messages-include="error-messages">
<div ng-message="pattern">密码需包含字母和数字,至少8位</div>
</div>
九、表单提交处理
9.1 方式一:ng-submit
<form name="myForm" ng-submit="onSubmit()" novalidate>
<input name="name" ng-model="user.name" required>
<button type="submit">提交</button>
</form>
$scope.onSubmit = function() {
if ($scope.myForm.$valid) {
// 提交逻辑
console.log($scope.user);
}
};
9.2 方式二:ng-click
<form name="myForm" novalidate>
<input name="name" ng-model="user.name" required>
<button type="button" ng-click="onSubmit()" ng-disabled="myForm.$invalid">
提交
</button>
</form>
9.3 方式三:阻止默认提交 + 手动验证
<form name="myForm" ng-submit="onSubmit($event)" novalidate>
<input name="name" ng-model="user.name" required>
<button type="submit">提交</button>
</form>
$scope.onSubmit = function(event) {
event.preventDefault();
// 标记所有控件为 dirty,触发错误显示
angular.forEach($scope.myForm.$error, function(controls, validationType) {
angular.forEach(controls, function(control) {
control.$setDirty();
});
});
if ($scope.myForm.$valid) {
// 提交
}
};
十、自定义验证
10.1 使用指令添加自定义验证
// 验证用户名是否已存在(异步验证)
angular.module('myApp')
.directive('usernameExists', ['$q', 'UserService', function($q, UserService) {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
// 同步验证器
ngModelCtrl.$validators.invalidChars = function(modelValue, viewValue) {
var value = modelValue || viewValue;
// 不允许包含特殊字符
return /^[a-zA-Z0-9_]+$/.test(value);
};
// 异步验证器
ngModelCtrl.$asyncValidators.usernameExists = function(modelValue, viewValue) {
var value = modelValue || viewValue;
if (!value) return $q.resolve();
return UserService.checkUsername(value).then(function(exists) {
if (exists) {
return $q.reject('用户名已存在');
}
return true;
});
};
}
};
}]);
<input type="text"
name="username"
ng-model="user.username"
required
username-exists>
<div ng-messages="myForm.username.$error"
ng-if="myForm.username.$dirty">
<div ng-message="required">用户名必填</div>
<div ng-message="invalidChars">用户名只能包含字母、数字和下划线</div>
<div ng-message="usernameExists">用户名已存在</div>
</div>
10.2 密码确认验证
angular.module('myApp')
.directive('passwordMatch', [function() {
return {
require: 'ngModel',
scope: {
passwordMatch: '='
},
link: function(scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$validators.passwordMatch = function(modelValue) {
return modelValue === scope.passwordMatch;
};
scope.$watch('passwordMatch', function() {
ngModelCtrl.$validate();
});
}
};
}]);
<input type="password" name="password" ng-model="user.password" required>
<input type="password"
name="confirmPassword"
ng-model="user.confirmPassword"
required
password-match="user.password">
<div ng-messages="myForm.confirmPassword.$error"
ng-if="myForm.confirmPassword.$dirty">
<div ng-message="required">请确认密码</div>
<div ng-message="passwordMatch">两次密码不一致</div>
</div>
十一、动态表单
11.1 ng-repeat 生成表单
<form name="surveyForm" ng-controller="SurveyController">
<div ng-repeat="question in questions">
<label>{{ question.text }}</label>
<!-- 单选题 -->
<div ng-if="question.type === 'radio'">
<label ng-repeat="option in question.options">
<input type="radio"
name="q{{ $parent.$index }}"
ng-model="question.answer"
ng-value="option.value">
{{ option.label }}
</label>
</div>
<!-- 多选题 -->
<div ng-if="question.type === 'checkbox'">
<label ng-repeat="option in question.options">
<input type="checkbox"
ng-model="question.answers[option.value]">
{{ option.label }}
</label>
</div>
<!-- 文本题 -->
<div ng-if="question.type === 'text'">
<input type="text" ng-model="question.answer">
</div>
</div>
<button ng-click="submit()" ng-disabled="surveyForm.$invalid">提交</button>
</form>
11.2 动态 ng-required
<!-- 根据条件决定是否必填 -->
<input type="text"
name="companyName"
ng-model="user.companyName"
ng-required="user.type === 'enterprise'">
<!-- 如果用户类型是企业,则公司名称必填 -->
<select ng-model="user.type">
<option value="personal">个人</option>
<option value="enterprise">企业</option>
</select>
十二、表单重置
$scope.resetForm = function() {
// 1. 重置模型数据
$scope.user = {
name: '',
email: '',
age: null
};
// 2. 重置表单状态
$scope.myForm.$setPristine(); // 恢复为原始状态
$scope.myForm.$setUntouched(); // 恢复为未触碰状态
};
<button type="button" ng-click="resetForm()">重置</button>
十三、$setValidity 手动设置验证状态
// 在指令或控制器中手动设置验证状态
ngModelCtrl.$setValidity('customError', false); // 标记为无效
ngModelCtrl.$setValidity('customError', true); // 标记为有效
// 在控制器中通过表单访问
$scope.myForm.username.$setValidity('taken', false);
<div ng-message="taken">该用户名已被占用</div>
十四、完整实战示例:注册表单
<!DOCTYPE html>
<html ng-app="regApp">
<head>
<meta charset="UTF-8">
<title>注册表单</title>
<script src="angular.js"></script>
<script src="angular-messages.js"></script>
<style>
.form-group { margin-bottom: 15px; }
.form-group label { display: block; margin-bottom: 5px; font-weight: bold; }
input.ng-dirty.ng-valid { border: 2px solid #4caf50; }
input.ng-dirty.ng-invalid { border: 2px solid #f44336; }
input.ng-pristine { border: 2px solid #ccc; }
.error-messages { color: #f44336; font-size: 0.85em; margin-top: 4px; }
.error-messages div { margin-top: 2px; }
button:disabled { opacity: 0.5; cursor: not-allowed; }
</style>
</head>
<body ng-controller="RegController">
<h2>用户注册</h2>
<form name="regForm" ng-submit="register()" novalidate>
<div class="form-group">
<label>用户名</label>
<input type="text"
name="username"
ng-model="user.username"
required
ng-minlength="3"
ng-maxlength="20"
ng-pattern="/^[a-zA-Z0-9_]+$/"
placeholder="3-20位字母、数字或下划线">
<div class="error-messages"
ng-messages="regForm.username.$error"
ng-if="regForm.username.$dirty">
<div ng-message="required">用户名必填</div>
<div ng-message="minlength">用户名至少3个字符</div>
<div ng-message="maxlength">用户名最多20个字符</div>
<div ng-message="pattern">只能包含字母、数字和下划线</div>
</div>
</div>
<div class="form-group">
<label>邮箱</label>
<input type="email"
name="email"
ng-model="user.email"
required
placeholder="example@domain.com">
<div class="error-messages"
ng-messages="regForm.email.$error"
ng-if="regForm.email.$dirty">
<div ng-message="required">邮箱必填</div>
<div ng-message="email">邮箱格式不正确</div>
</div>
</div>
<div class="form-group">
<label>密码</label>
<input type="password"
name="password"
ng-model="user.password"
required
ng-minlength="8"
ng-pattern="/^(?=.*[A-Za-z])(?=.*\d)/"
placeholder="至少8位,包含字母和数字">
<div class="error-messages"
ng-messages="regForm.password.$error"
ng-if="regForm.password.$dirty">
<div ng-message="required">密码必填</div>
<div ng-message="minlength">密码至少8个字符</div>
<div ng-message="pattern">密码需包含字母和数字</div>
</div>
</div>
<div class="form-group">
<label>确认密码</label>
<input type="password"
name="confirmPwd"
ng-model="user.confirmPwd"
required
password-match="user.password"
placeholder="再次输入密码">
<div class="error-messages"
ng-messages="regForm.confirmPwd.$error"
ng-if="regForm.confirmPwd.$dirty">
<div ng-message="required">请确认密码</div>
<div ng-message="passwordMatch">两次密码不一致</div>
</div>
</div>
<div class="form-group">
<label>年龄</label>
<input type="number"
name="age"
ng-model="user.age"
required
min="1"
max="150"
placeholder="1-150">
<div class="error-messages"
ng-messages="regForm.age.$error"
ng-if="regForm.age.$dirty">
<div ng-message="required">年龄必填</div>
<div ng-message="min">年龄不能小于1</div>
<div ng-message="max">年龄不能大于150</div>
<div ng-message="number">请输入有效数字</div>
</div>
</div>
<div class="form-group">
<label>
<input type="checkbox" ng-model="user.agree" required>
我已阅读并同意服务条款
</label>
</div>
<button type="submit" ng-disabled="regForm.$invalid">
注册
</button>
<button type="button" ng-click="reset()">重置</button>
</form>
<pre ng-show="submitted">{{ user | json }}</pre>
</body>
</html>
angular.module('regApp', ['ngMessages'])
.directive('passwordMatch', [function() {
return {
require: 'ngModel',
scope: { passwordMatch: '=' },
link: function(scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$validators.passwordMatch = function(modelValue) {
return modelValue === scope.passwordMatch;
};
scope.$watch('passwordMatch', function() {
ngModelCtrl.$validate();
});
}
};
}])
.controller('RegController', ['$scope', '$http', function($scope, $http) {
$scope.user = {};
$scope.submitted = false;
$scope.register = function() {
if ($scope.regForm.$valid) {
$http.post('/api/register', $scope.user)
.then(function(response) {
$scope.submitted = true;
alert('注册成功!');
}, function(error) {
alert('注册失败:' + error.data.message);
});
}
};
$scope.reset = function() {
$scope.user = {};
$scope.submitted = false;
$scope.regForm.$setPristine();
$scope.regForm.$setUntouched();
};
}]);
十五、常见问题与注意事项
15.1 novalidate
<!-- 始终添加 novalidate,禁用浏览器原生验证 -->
<form name="myForm" novalidate>
不添加 novalidate 会导致浏览器原生验证和 AngularJS 验证同时生效,产生冲突。
15.2 type=“number” 的坑
<!-- type="number" 时,非数字输入不会更新 ng-model -->
<input type="number" ng-model="user.age">
<!-- 如果需要允许任意输入并自行验证,用 type="text" + ng-pattern -->
<input type="text" ng-model="user.age" ng-pattern="/^\d+$/">
15.3 checkbox 的 required 验证
<!-- checkbox 的 required 验证:必须勾选 -->
<input type="checkbox" ng-model="user.agree" name="agree" required>
<span ng-show="myForm.agree.$dirty && myForm.agree.$error.required">
必须同意条款
</span>
15.4 select 的默认空值
<!-- select 的第一个 option 为空值时,ng-model 不会自动选中 -->
<select ng-model="user.city" required>
<option value="">请选择</option>
<option value="bj">北京</option>
<option value="sh">上海</option>
</select>
<!-- 使用 ng-options 更推荐 -->
<select ng-model="user.city"
ng-options="city.code as city.name for city in cities"
required>
<option value="">请选择</option>
</select>
15.5 表单嵌套
<!-- AngularJS 不支持 form 嵌套,用 ng-form 替代内层 -->
<form name="outerForm" ng-submit="submit()">
<div ng-form="addressForm">
<input name="city" ng-model="address.city" required>
<span ng-show="addressForm.city.$error.required">城市必填</span>
</div>
<div ng-form="contactForm">
<input name="phone" ng-model="contact.phone" required>
<span ng-show="contactForm.phone.$error.required">电话必填</span>
</div>
<button type="submit" ng-disabled="outerForm.$invalid">提交</button>
</form>
ng-form 与 form 功能相同,但不会创建新的 HTML <form> 元素,支持嵌套,且子表单的验证状态会冒泡到父表单。
十六、总结思维导图
AngularJS Form
├── 核心指令
│ ├── ng-model ────── 双向绑定
│ ├── ng-submit ───── 表单提交
│ ├── ng-form ─────── 嵌套表单
│ └── novalidate ──── 禁用原生验证
├── 状态追踪
│ ├── $pristine / $dirty ── 是否修改
│ ├── $valid / $invalid ── 验证结果
│ ├── $touched / $untouched ── 焦点状态
│ ├── $submitted ── 是否提交
│ └── $error ── 错误详情
├── 自动 CSS 类
│ ├── ng-pristine / ng-dirty
│ ├── ng-valid / ng-invalid
│ ├── ng-touched / ng-untouched
│ └── ng-valid-xxx / ng-invalid-xxx
├── 内置验证
│ ├── required / ng-required
│ ├── minlength / maxlength
│ ├── min / max
│ ├── pattern / ng-pattern
│ └── type="email" / "url" / "number"
├── ngMessages
│ ├── ng-messages ── 消息容器
│ ├── ng-message ── 单条消息
│ ├── ng-messages-multiple ── 显示多条
│ └── ng-messages-include ── 复用模板
├── 自定义验证
│ ├── $validators ── 同步验证
│ ├── $asyncValidators ── 异步验证
│ ├── $setValidity() ── 手动设置
│ └── 自定义指令
├── 表单操作
│ ├── $setPristine() ── 重置为原始
│ ├── $setUntouched() ── 重置为未触碰
│ └── $rollbackViewValue() ── 回滚
└── 注意事项
├── 必须加 novalidate
├── type="number" 的坑
├── ng-form 替代嵌套 form
└── select 默认空值问题
以上内容覆盖了 AngularJS 表单的双向绑定、状态追踪、内置验证、ngMessages、自定义验证、动态表单、表单重置等核心知识点,可作为系统学习和日常开发的完整参考。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)