点击查看AngularJS系列目录
转载请注明出处:http://www.cnblogs.com/leosx/
Angular表单
input
, select
, textarea
控件都是给用户输入数据用的。窗体和控件提都提供了验证服务,使得在用户输入了无效数据的情况下,提交表单之前就可以得到知道。这样的验证远远比只在服务端进行验证好得多,因为在前端验证,用户可以得到很好的用户输入错误的反馈!提高用户体验。请记住,在客户端进行验证是用户体验的非常重要的组成部分。但是它很容易就可以被篡改,所以我们是不能信赖前端验证的,后端依旧得进行验证。
一个简单的表单
文件一:index.html
<div ng-controller="ExampleController">
<form novalidate class="simple-form">
Name: <input type="text" ng-model="user.name" /><br />
E-mail: <input type="email" ng-model="user.email" /><br />
Gender: <input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female<br />
<input type="button" ng-click="reset()" value="Reset" />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
<pre>user = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div> <script>
angular.module('formExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.master = {}; $scope.update = function(user) {
$scope.master = angular.copy(user);
}; $scope.reset = function() {
$scope.user = angular.copy($scope.master);
}; $scope.reset();
}]);
</script>
效果图:
当点击Reset按钮的时候,就会把user对象给重置为原来保存的对象。
请注意:novalidate
用来禁用掉原生的浏览器表单验证。如果验证不通过,那么ngModel
所绑定的model的对应值是不会改变的。
样式的使用
使用样式,我们可以更好的控制表单控件,例如:ngModel
指令就为对应的元素增加了如下样式:
1、
ng-valid
: 模型(model)验证通过2、
ng-invalid
: 模型(model)验证失败3、
ng-valid-[key]
: 通过$setValidity
增加的验证通过的密匙()4、
ng-invalid-[key]
: 通过$setValidity
增加的验证失败的密匙5、
ng-pristine
: 还没有与controller进行互动。6、
ng-dirty
: 控制器与之有互动7、
ng-touched
: 已经失去控制8、
ng-untouched
: 还未失去控制9、
ng-pending
: 异步验证($asyncValidators
)还未结束
下面的示例使用CSS来显示每个表单控件的有效性。例子中,user.name
和 user.email
是必须的,当失去焦点时,会进行验证,如果验证不通过,那么背景色会变成红色的。这确保了用户不会忽略掉错误,知道验证通过了,才会同步到controller的model中去。
文件一:index.html
<div ng-controller="ExampleController">
<form novalidate class="css-form">
Name: <input type="text" ng-model="user.name" required /><br />
E-mail: <input type="email" ng-model="user.email" required /><br />
Gender: <input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female<br />
<input type="button" ng-click="reset()" value="Reset" />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
<pre>user = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div> <style type="text/css">
.css-form input.ng-invalid.ng-touched {
background-color: #FA787E;
} .css-form input.ng-valid.ng-touched {
background-color: #78FA89;
}
</style> <script>
angular.module('formExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.master = {}; $scope.update = function(user) {
$scope.master = angular.copy(user);
}; $scope.reset = function() {
$scope.user = angular.copy($scope.master);
}; $scope.reset();
}]);
</script>
绑定表单状态和控件状态
Angular的一个表单就是一个FormController的实例对象。表单的实例对象可以使用name
属性有选择的发布到scope上去。
同样的,input控件都会具有一个NgModelController的实例ngModel 指令。这种input控件(表单实例)的实例可以通过name
属性所对应的控件上,再发布一个属性。
这使我们能够扩展上面的例子有以下功能:
1、如果有自定义错误,那么用户和控件交互后,会被触发判断,如果有错,将会立即显示提示消息(如果设置了$touched,那么手机上触摸也会执行)。
2、当用户点击submit按钮(
$submitted
)的时候,即使之前没有执行交互,那么一样会触发自定义验证,并显示错误消息。
文件一:index.html
<div ng-controller="ExampleController">
<form name="form" class="css-form" novalidate>
Name:
<input type="text" ng-model="user.name" name="uName" required="" />
<br />
<div ng-show="form.$submitted || form.uName.$touched">
<div ng-show="form.uName.$error.required">Tell us your name.</div>
</div> E-mail:
<input type="email" ng-model="user.email" name="uEmail" required="" />
<br />
<div ng-show="form.$submitted || form.uEmail.$touched">
<span ng-show="form.uEmail.$error.required">Tell us your email.</span>
<span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
</div> Gender:
<input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female
<br />
<input type="checkbox" ng-model="user.agree" name="userAgree" required="" /> I agree:
<input ng-show="user.agree" type="text" ng-model="user.agreeSign" required="" />
<br />
<div ng-show="form.$submitted || form.userAgree.$touched">
<div ng-show="!user.agree || !user.agreeSign">Please agree and sign.</div>
</div> <input type="button" ng-click="reset(form)" value="Reset" />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
<pre>user = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div>
文件二:script.js
angular.module('formExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.master = {}; $scope.update = function(user) {
$scope.master = angular.copy(user);
}; $scope.reset = function(form) {
if (form) {
form.$setPristine();
form.$setUntouched();
}
$scope.user = angular.copy($scope.master);
}; $scope.reset();
}]);
效果图:
自定义模型的更新触发时机(WPF中的更新时间)
默认情况下,任何内容的改变将触发表单验证和model的更新。你可以通过ngModelOptions指令绑定到一个事件集合中来重写触发的时间,例如:ng-model-options="{ updateOn: 'blur' }"
将会在控件失去焦点后执行表单验证和更新Model。你可以使用空格来分割多个事件的触发验证和更新的时间。例如:ng-model-options="{ updateOn: 'mousedown blur' }"
。
如果你想更改默认的触发时机,你可以使用"default" 来指定:
例如:ng-model-options="{ updateOn: 'default blur' }"
下面的例子展示了如何重写更新时机。修改触发时机为失去焦点时执行触发验证和更新。
文件一:index.html
<div ng-controller="ExampleController">
<form>
Name:
<input type="text" ng-model="user.name" ng-model-options="{ updateOn: 'blur' }" /><br />
Other data:
<input type="text" ng-model="user.data" /><br />
</form>
<pre>username = "{{user.name}}"</pre>
<pre>userdata = "{{user.data}}"</pre>
</div>
文件二:script.js
angular.module('customTriggerExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.user = {};
}]);
效果演示:
延迟更新和验证时间
你可以使用ngModelOptions 指令来延迟Model的验证和更新时间。这种延迟同样适用于parsers(解析器)、validators(验证器)、model标签(eg:$dirty
或者 $pristine
)
例如:ng-model-options="{ debounce: 500 }"
会在出发之后延迟500毫秒再执行验证和更新model。
如果自定义的触发器被使用,那么我们可以使用debounce
来为每个自定义的触发器指定延迟时间。
例如:ng-model-options="{ updateOn: 'default blur', debounce: { default: 500, blur: 0 } }"
如果这些属性被加到一个元素上去,那么这种机制会应用到这个元素下的所有子元素下,也就是会继承这种机制,除非子元素重写了这种机制。
我们来看下面的例子,验证动作和model的更新将会在最后一次更改input内容250毫秒后执行。
文件一:index.html
<div ng-controller="ExampleController">
<form>
Name:
<input type="text" ng-model="user.name" ng-model-options="{ debounce: 250 }" /><br />
</form>
<pre>username = "{{user.name}}"</pre>
</div>
文件二:script.js
angular.module('debounceExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.user = {};
}]);
效果图:
自定义验证
Angular提供了对HTML5最常用的表单控件的实现(text, number, url, email, date, radio, checkbox),同样的,相同的验证也有被重写:(required
, pattern
, minlength
, maxlength
, min
, max
).
通过自定义指令,你可以通过对ngModelController
对象的$validators
实例(也就是ng-model指令)添加自己的验证功能,在下面的示例中,我们会用到。
$validators
对象上的每一个验证函数都将modelValue
和 viewValue
做为参数。接着Angular会调用$setValidity
方法,它会返回(true
: valid【验证通过】, false
: invalid【验证失败】)。验证函数会在每次输入改变的时候执行($setViewValue
被调用),或者触发时机被修改了,一样会触发验证。当分别成功执行了$parsers
和$formatters
方法后,会执行验证(Validation),如果验证错误,那么会把错误信息保存到ngModelController.$error
对象中去。
此外,$asyncValidators
对象可以进行异步验证,它就相当于使用$http
去调用后台执行验证。这个验证方法必须承诺当验证通过时,返回resolved
;当验证失败时,返回rejected
;执行异步验证的结果将会保存到ngModelController.$pending
中去。
下面的例子中,我们创建了两个指令:
1、
integer
指令用于验证输入的值是否是数字(int类型),例如:1.23
将会验证失败,因为它有小数部分。注意,我们这里验证的是view(视图)中的控件的输入值,并不是控件对应的model的值。因为只有成功的执行了$parsers
方法后,才会将数据更新到model的对应属性中去。2、
username
指令用于异步验证用户名。如果该用户已经存在,那么会给出提示!这里,我们使用$q
来模拟从服务器验证。
文件一:index.html
<form name="form" class="css-form" novalidate>
<div>
Size (integer 0 - 10):
<input type="number" ng-model="size" name="size"
min="0" max="10" integer />{{size}}<br />
<span ng-show="form.size.$error.integer">The value is not a valid integer!</span>
<span ng-show="form.size.$error.min || form.size.$error.max">
The value must be in range 0 to 10!</span>
</div> <div>
Username:
<input type="text" ng-model="name" name="name" username />{{name}}<br />
<span ng-show="form.name.$pending.username">Checking if this name is available...</span>
<span ng-show="form.name.$error.username">This username is already taken!</span>
</div> </form>
文件二:script.js
var app = angular.module('form-example1', []); var INTEGER_REGEXP = /^\-?\d+$/;
app.directive('integer', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.integer = function(modelValue, viewValue) {
if (ctrl.$isEmpty(modelValue)) {
// consider empty models to be valid
return true;
} if (INTEGER_REGEXP.test(viewValue)) {
// it is valid
return true;
} // it is invalid
return false;
};
}
};
}); app.directive('username', function($q, $timeout) {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
var usernames = ['Jim', 'John', 'Jill', 'Jackie']; ctrl.$asyncValidators.username = function(modelValue, viewValue) { if (ctrl.$isEmpty(modelValue)) {
// consider empty model valid
return $q.when();
} var def = $q.defer(); $timeout(function() {
// Mock a delayed response
if (usernames.indexOf(modelValue) === -1) {
// The username is available
def.resolve();
} else {
def.reject();
} }, 2000); return def.promise;
};
}
};
});
效果图:
修改内置的验证机制
自从Angular使用了$validators
来进行校验数据,你就可以很轻松的替换掉默认的数据验证方式。下面的例子中,我们使用自定义的指令重写了表单中邮件input[email]
的验证方式。注意,你也可以使用ng-pattern
指令来进一步限制验证。
文件一:index.html
<form name="form" class="css-form" novalidate>
<div>
Overwritten Email:
<input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
<span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
Model: {{myEmail}}
</div>
</form>
文件二:script.js
var app = angular.module('form-example-modify-validators', []); app.directive('overwriteEmail', function() {
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i; return {
require: 'ngModel',
restrict: '',
link: function(scope, elm, attrs, ctrl) {
// only apply the validator if ngModel is present and Angular has added the email validator
if (ctrl && ctrl.$validators.email) { // this will overwrite the default Angular email validator
ctrl.$validators.email = function(modelValue) {
return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
};
}
}
};
});
效果图:
实现自定义表单控件(使用 ngModel
)
Angular实现了基本的HTML表单控件(input, select, textarea),他们可以满足大部分需求了。为了更好的灵活性,你也可以通过指令来自定义属于自己的表单控件。
为了使得自定义控件可以很好的和ngModel
指令进行数据的双向通信,你需要:
1、实现
$render
方法,它负责在NgModelController.$formatters
后,呈现数据。2、调用
$setViewValue
方法,当用户与控件进行交互,需要进行model的更新时。这个动作通常在一个DOM事件监听器里完成的。
点击这里,查看关于$compileProvider.directive
的更多信息。
下面的例子展示了如何为contentEditable元素增加的数据的双向绑定。
文件一:index.html
<div contentEditable="true" ng-model="content" title="Click to edit">Some</div>
<pre>model = {{content}}</pre> <style type="text/css">
div[contentEditable] {
cursor: pointer;
background-color: #D0D0D0;
}
</style>
文件二:script.js
angular.module('form-example2', []).directive('contenteditable', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
// view -> model
elm.on('blur', function() {
ctrl.$setViewValue(elm.html());
}); // model -> view
ctrl.$render = function() {
elm.html(ctrl.$viewValue);
}; // load init value from DOM
ctrl.$setViewValue(elm.html());
}
};
});
效果图:
Angularjs-Forms(表单)的更多相关文章
-
【AngularJs】---表单验证
1. 必填项 验证某个表单输入是否已填写,只要在输入字段元素上添加HTML5标记required即可: <input type="text" required /> 2 ...
-
angularJS 过滤器 表单验证
过滤器1.filter的作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果,主要用于数据的格式化.2.内置过滤器(1)Currency(货币)将一个数值格式化为货币格式,默认为$(2)D ...
-
AngularJS实现表单手动验证和表单自动验证
AngularJS的表单验证大致有两种,一种是手动验证,一种是自动验证.一.手动验证 所谓手动验证是通过AngularJS表单的属性来验证.而成为AngularJS表单必须满足两个条件: 1.给for ...
-
页面注册系统--使用forms表单结合ajax
页面注册系统--使用forms表单结合ajax 在Django中通过forms构建一个表单 1.urls.py 配置路由 from django.conf.urls import url from d ...
-
Python的Django框架中forms表单类的使用方法详解
用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...
-
基于angularJS的表单验证练习
今天看了一下angularJS的表单验证,看的有点云里雾里(也有可能是雾霾吸多了),于是做了一个小练习来巩固一下. html: <div ng-controller="Aaa" ...
-
django实现密码加密的注册(数据对象插入)-结合forms表单实现表单验证
forms表单 #_*_coding:utf-8_*_ from django import forms class regis(forms.Form): username = forms.CharF ...
-
夺命雷公狗—angularjs—3—表单验证的高级用法
其实我们的angularjs都是是块状代码,其实是可以在实际开发中保存下来以后就可以达到重复利用的目的了.. 废话不多说,直接上代码: <!doctype html> <html l ...
-
AngularJS 模块&; 表单
模块定义了一个应用程序. 模块是应用程序中不同部分的容器. 模块是应用控制器的容器. 控制器通常属于一个模块. 应用("myApp") 带有控制器 ("myCtrl&qu ...
-
angularjs的表单验证
angularjs内置了常用的表单验证指令,比如min,require等.下面是演示: <!DOCTYPE html> <html> <head> <meta ...
随机推荐
-
Cordova+Ionic之坑
命令:ionic platform add android 报错:Unable to start the daemon process…… 解决: 1)添加环境变量[_JAVA_OPTIONS],值: ...
-
Service之来电监听(失败的案例)
Service:服务,可以理解成一个运行再后台没有界面的Activity,集成于Seriver,是四大组件之一 Service的继承关系:Service-->ContextWrapper--&g ...
-
负载均衡软件LVS分析三(配置)
LVS集群有DR.TUN.NAT三种配置模式,可以对www服务.FTP服务.MAIL服务等做负载均衡,下面通过搭建www服务的负载均衡实例,讲述基于DR模式的LVS集群配置. 一. Director ...
-
(NO.00001)iOS游戏SpeedBoy Lite成形记(六)
为了能让玩家可以在比赛结束时清楚看到每位选手的成绩,我们需要在GameScene场景的track对象中添加一些新的元素. 在SpriteBuilder中打开GameScene.ccb,创建1个标签对象 ...
-
关于Python课程的一些思考。
出于对网络爬虫的好奇,我选修了Python程序设计,至于pyhton还能干啥还不太清除,只觉得爬一些数据很有意思,所以希望老师讲一些数据分析之类的技术.学完课程希望能分析一些数据,比如:还有: 上课的 ...
-
SQL 自定义四舍五入
--============================================== -- 自定义的四舍五入(四舍五入后的所有尾数遇进则进) -- by 小天使 2015-11-12 -- ...
-
helm-chart-1-简单概念介绍-仓库搭建-在rancher上的使用
简单的概念介绍: Chart是helm管理的应用的打包格式,一个chart对应一个或一套应用.内部是一系列的yaml描述文件,以为为yaml 服务的文件. 三个部分,helm .tiller.repo ...
-
<;crtdbg.h>; 的作用
1.在调试状态下让win程在输出窗口中显示调试信息,可以用_RPTn 宏n为显示参数比如_RPT0(_CRT_WARN,"text"); _RPT1(_CRT_WARN," ...
-
Spring Cloud启动应用时指定IP或忽略某张网卡配置
说明:分布式应用部署到服务上,由于服务器可能存在多张网卡,造成IP地址不准的问题. 解决方法: 1.直接添加忽略某张网卡的配置: spring.cloud.inetutils.ignored-inte ...
-
[javaSE] 基本类型(String相关)
字符串是一个特殊的对象 字符串一旦初始化就不可以被改变 获取字符串的长度 调用String对象的length()方法,返回int长度 获取某个索引位置的字符 调用String对象的charAt()方法 ...