AngularJS ng-model 指令
·
AngularJS ng-model 指令
ng-model 是 AngularJS 中最重要的指令之一,用于实现双向数据绑定(Two-way Data Binding)。它将表单控件的值与作用域(Scope)中的属性绑定在一起,使得数据的变化能够自动同步。
一、基本概念
1. 什么是双向数据绑定
双向数据绑定意味着:
- 视图 → 模型:用户在表单控件中输入数据时,自动更新作用域中的变量
- 模型 → 视图:作用域中的变量变化时,自动更新表单控件的显示值
┌─────────────┐ ┌─────────────┐
│ 视图 │ ←→ │ 模型 │
│ (表单控件) │ │ (Scope变量) │
└─────────────┘ └─────────────┘
2. 基本语法
<input type="text" ng-model="变量名">
// 控制器中
$scope.name = "张三";
二、基本用法
1. 文本输入框
<div ng-app="myApp" ng-controller="MyCtrl">
<input type="text" ng-model="name" placeholder="请输入姓名">
<p>你输入的是:{{ name }}</p>
</div>
angular.module('myApp').controller('MyCtrl', function($scope) {
$scope.name = "初始值";
});
2. 文本域
<textarea ng-model="description" rows="4" cols="50"></textarea>
<p>描述:{{ description }}</p>
3. 数字输入
<input type="number" ng-model="age" min="0" max="120">
<p>年龄:{{ age }}</p>
三、不同表单控件的使用
1. 复选框
单个复选框
<input type="checkbox" ng-model="isChecked">
<p>状态:{{ isChecked ? "已选中" : "未选中" }}</p>
复选框组
<div ng-repeat="item in items">
<input type="checkbox"
ng-model="item.selected"
id="item-{{ $index }}">
<label for="item-{{ $index }}">{{ item.name }}</label>
</div>
<p>已选:{{ items | filter:{selected:true} | json }}</p>
$scope.items = [
{ name: '选项1', selected: false },
{ name: '选项2', selected: false },
{ name: '选项3', selected: false }
];
2. 单选框
<input type="radio" ng-model="gender" value="male"> 男
<input type="radio" ng-model="gender" value="female"> 女
<input type="radio" ng-model="gender" value="other"> 其他
<p>性别:{{ gender }}</p>
注意:所有单选框的 ng-model 必须相同,value 不同。
3. 下拉框
基本用法
<select ng-model="selectedCity">
<option value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select>
<p>选择的城市:{{ selectedCity }}</p>
使用 ng-options(推荐)
<select ng-model="selectedCity" ng-options="city.code as city.name for city in cities">
<option value="">-- 请选择 --</option>
</select>
<p>代码:{{ selectedCity }}</p>
<p>名称:{{ getCityName(selectedCity) }}</p>
$scope.cities = [
{ code: 'bj', name: '北京' },
{ code: 'sh', name: '上海' },
{ code: 'gz', name: '广州' }
];
$scope.getCityName = function(code) {
var city = $scope.cities.find(function(c) {
return c.code === code;
});
return city ? city.name : '';
};
ng-options 语法详解
<!-- 1. 数组:值作为显示文本 -->
<select ng-model="selected" ng-options="item for item in items"></select>
<!-- 2. 数组:值和显示文本不同 -->
<select ng-model="selected" ng-options="item.id as item.name for item in items"></select>
<!-- 3. 数组:分组 -->
<select ng-model="selected" ng-options="item.name group by item.category for item in items"></select>
<!-- 4. 对象:键值对 -->
<select ng-model="selected" ng-options="key as value for (key, value) in object"></select>
<!-- 5. 对象:键值对(值作为显示文本) -->
<select ng-model="selected" ng-options="key for (key, value) in object"></select>
四、ng-model 的修饰符
1. ng-model-options
控制数据绑定的行为。
<!-- 延迟更新(失去焦点时才更新) -->
<input type="text" ng-model="name" ng-model-options="{ updateOn: 'blur' }">
<!-- 防抖(延迟 500ms 更新) -->
<input type="text" ng-model="name" ng-model-options="{ debounce: 500 }">
<!-- 多事件触发 -->
<input type="text" ng-model="name" ng-model-options="{ updateOn: 'default blur', debounce: { default: 500, blur: 0 } }">
<!-- 允许无效值 -->
<input type="email" ng-model="email" ng-model-options="{ allowInvalid: true }">
2. ng-trim
自动去除输入值的首尾空格(默认为 true)。
<!-- 自动去除空格 -->
<input type="text" ng-model="name" ng-trim="true">
<!-- 保留空格 -->
<input type="text" ng-model="name" ng-trim="false">
五、表单验证与 ng-model
ng-model 与表单验证紧密相关,通过 $error 和 $valid/$invalid 等属性进行验证。
1. 基本验证
<form name="myForm" novalidate>
<input type="text"
name="username"
ng-model="username"
required
ng-minlength="3"
ng-maxlength="10"
ng-pattern="/^[a-zA-Z]+$/">
<p ng-show="myForm.username.$error.required">用户名必填</p>
<p ng-show="myForm.username.$error.minlength">至少3个字符</p>
<p ng-show="myForm.username.$error.maxlength">最多10个字符</p>
<p ng-show="myForm.username.$error.pattern">只能包含字母</p>
<p>有效:{{ myForm.username.$valid }}</p>
<p>无效:{{ myForm.username.$invalid }}</p>
<p>脏:{{ myForm.username.$dirty }}</p>
<p>原始:{{ myForm.username.$pristine }}</p>
</form>
2. 表单状态属性
| 属性 | 说明 |
|---|---|
$valid |
表单/字段是否有效 |
$invalid |
表单/字段是否无效 |
$pristine |
表单/字段是否未被修改 |
$dirty |
表单/字段是否已被修改 |
$touched |
表单/字段是否已被触碰 |
$untouched |
表单/字段是否未被触碰 |
$error |
包含所有验证错误的对象 |
3. 实时验证示例
<form name="myForm" novalidate>
<div class="form-group" ng-class="{ 'has-error': myForm.email.$invalid && myForm.email.$dirty }">
<label>邮箱</label>
<input type="email"
name="email"
ng-model="email"
required>
<p class="help-block" ng-show="myForm.email.$error.required && myForm.email.$dirty">邮箱必填</p>
<p class="help-block" ng-show="myForm.email.$error.email && myForm.email.$dirty">邮箱格式不正确</p>
</div>
<button type="submit" ng-disabled="myForm.$invalid">提交</button>
</form>
六、高级用法
1. 自定义指令中使用 ng-model
angular.module('myApp').directive('myInput', function() {
return {
restrict: 'E',
require: 'ngModel',
template: '<input type="text" ng-model="ngModel">',
scope: {
ngModel: '='
},
link: function(scope, element, attrs, ngModelCtrl) {
// 访问 ngModelController
ngModelCtrl.$formatters.push(function(value) {
// 格式化模型值到视图
return value ? value.toUpperCase() : '';
});
ngModelCtrl.$parsers.push(function(value) {
// 解析视图值到模型
return value ? value.toLowerCase() : '';
});
}
};
});
2. $formatters 和 $parsers
// 在控制器中
$scope.$watch('price', function(newVal) {
// 监听模型变化
});
// 在自定义指令中
link: function(scope, element, attrs, ngModelCtrl) {
// 模型 → 视图(格式化)
ngModelCtrl.$formatters.push(function(modelValue) {
return modelValue ? modelValue.toFixed(2) : '';
});
// 视图 → 模型(解析)
ngModelCtrl.$parsers.push(function(viewValue) {
return parseFloat(viewValue);
});
}
3. $validators 和 $asyncValidators
// 同步验证
ngModelCtrl.$validators.custom = function(modelValue, viewValue) {
return modelValue && modelValue.length >= 3;
};
// 异步验证
ngModelCtrl.$asyncValidators.unique = function(modelValue, viewValue) {
return $http.get('/api/check-username', { username: modelValue })
.then(function(response) {
return response.data.available;
});
};
七、常见问题与最佳实践
1. 避免在 ng-repeat 中直接使用原始类型
<!-- 不推荐 -->
<div ng-repeat="item in [1, 2, 3]">
<input type="checkbox" ng-model="item">
</div>
<!-- 推荐 -->
<div ng-repeat="item in items">
<input type="checkbox" ng-model="item.checked">
</div>
2. 使用 ng-model-options 优化性能
<!-- 搜索框:使用防抖减少更新频率 -->
<input type="text"
ng-model="searchText"
ng-model-options="{ debounce: 300 }"
placeholder="搜索...">
3. 处理初始值
// 确保模型有初始值
$scope.user = {
name: '',
email: '',
gender: 'male' // 默认值
};
4. 避免在表达式中直接修改模型
<!-- 不推荐 -->
<input type="text" ng-model="name" ng-change="name = name.toUpperCase()">
<!-- 推荐 -->
<input type="text" ng-model="name" ng-change="formatName()">
$scope.formatName = function() {
$scope.name = $scope.name.toUpperCase();
};
八、总结
ng-model 是 AngularJS 双向数据绑定的核心,通过它可以轻松实现表单控件与模型数据的同步。掌握 ng-model 的各种用法、修饰符和验证机制,是构建响应式表单应用的关键。
关键点:
- 双向绑定:视图 ↔ 模型自动同步
- 支持多种表单控件:文本、复选框、单选框、下拉框
- 配合表单验证:
$valid,$invalid,$error - 修饰符:
ng-model-options,ng-trim - 高级功能:
$formatters,$parsers,$validators
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)