表单控件(input, select, textarea )是用来获取用户输入的。表单则是一组有联系的表单控件的集合。用户能通过表单和表单控件提供验证的服务,知道自己的输入是否合法。这样能让用户交互变得友好,因为用户能通过反馈来修正自己的错误。不过,虽然客户端的验证能够起到很大作用,但也很容易被绕过,所以不能完全依靠客户端验证。 要建立安全的应用,服务器端验证还是必不可少的。了解AngularJS双向绑定的关键在于了解
ngModel指令。这个指令通过动态将model和view互相映射,来实现双向绑定。为了能美化表单和表单元素,ngModel指令会自动为元素添加以下css类:
- ng-valid
- ng-invalid
- ng-pristine
- ng-dirty
一个表单就是一个
FormController的实例,表单实例可以通过name属性选择性地公开到作用域中。同样的,一个表单控件也是一个
NgModelController的实例,表单控件也能同样的被公开到作用域中。这意味视图能通过绑定的基本功能获取表单或者表单控件的状态。
- 只有当表单发生改变时,重置按钮才会被显示出来。
- 只有当表单有改变并且改变的值都是合法的,保存按钮才会被显示出来。
- 能自定义user.email和user.agree的错误信息。
举个例子: <!doctype html><html ng-app><head><script src="http://code.angularjs.org/angular-1.0.2.min.js"></script><script>function Controller($scope) { $scope.master= {}; $scope.update = function(user) { $scope.master= angular.copy(user); }; $scope.reset = function() { $scope.user = angular.copy($scope.master); }; $scope.isUnchanged = function(user) { return angular.equals(user, $scope.master); }; $scope.reset(); }</script></head><body><div ng-controller="Controller"><form name="form" class="css-form" novalidate> //novalidate是用来屏蔽浏览器本身的验证功能的。Name:<input type="text" ng-model="user.name" name="uName" required /><br />//required,此输入框必须有内容E-mail:<input type="email" ng-model="user.email" name="uEmail" required/><br /><div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">Invalid: //此div,如果form表中的name为uEmail的input元素中的内容违法或者是脏数据,那么就显示出来。<span ng-show="form.uEmail.$error.required">Tell us your email.</span> //如果错误信息是由required引起的,就显示此span<span ng-show="form.uEmail.$error.email">This is not a valid email.</span>//如果错误信息是由里面的内容不合法引起的,就显示此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="!user.agree || !user.agreeSign">Please agree and sign.</div><button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button><button ng-click="update(user)" ng-disabled="form.$invalid || isUnchanged(user)">SAVE</button>//如果整个form表单没有通过验证或者form表单中的内容没有发生改变,此按钮就不可点击</form></div></body></html> AngularJS实现了大部分常见的html5表单输入元素(text, number, url, email, radio, checkbox),也实现了很多用于验证的指令(required, pattern, minlength, maxlength, min, max)。如果想要定义你自己的验证器的话,可以通过在你自己的指令中添加一个验证函数给ngModel的控制器来实现。要想获得控制器的引用,需要在指令中指定依赖,验证函数可以写在两个地方。
- 模型到视图的更新中- 只要绑定的模型改变了,NgModelController#$formatters数组中的函数就会被轮流调用,所以每一个函数都有机会对数据进行格式化,当然你也可以通过NgModelController#$setValidity来改变表单的验证状态。
- 视图到模型的更新中- 相同的,只要用户与表单交互了,NgModelController#$setViewValue就会被调用。 这次是NgModelController#$parsers数组中的函数会被依次调用,每个函数都有机会来改变值或者通过NgModelController#$setValidity来改变表单的验证状态。下面的例子,使用的是这个。
举个例子: <!doctype html><html ng-app="form-example1"><head><script src="http://code.angularjs.org/angular-1.0.2.min.js"></script><script> var app = angular.module("form-example1", []); var INTEGER_REGEXP = /^-?d+$/; //或者以"-"(负)开头,或者没有负号,后面都是正整数,包括0 app.directive("integer", function() { return { require: "ngModel",//依赖nogModel指令 link: function(scope, elm, attrs, ctrl) { ctrl.$parsers.unshift(function(viewValue) {//ctrl可以调用ngModel指令中controller函数中定义的方法 if (INTEGER_REGEXP.test(viewValue)) { ctrl.$setValidity("integer", true); return viewValue; } else { ctrl.$setValidity("integer", false); return undefined; } }); } }; }); var FLOAT_REGEXP = /^-?d+((.|,)d+)?$/;//可以是正负,可以是整数,也可以是浮点数,浮点数可以用"."分开,也可以用","分开。 app.directive("smartFloat", function() { return { require: "ngModel", link: function(scope, elm, attrs, ctrl) { ctrl.$parsers.unshift(function(viewValue) { if (FLOAT_REGEXP.test(viewValue)) { ctrl.$setValidity("float", true); return parseFloat(viewValue.replace(",", ".")); } else { ctrl.$setValidity("float", false); return undefined; } }); } }; });</script></head><body><div ng-controller="Controller"><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 /> //integer,自定义指令<span ng-show="form.size.$error.integer">This is not 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>Length (float):<input type="text" ng-model="length" name="length" smart-float />{{length}}<br /> //smart-float,自定义指令<span ng-show="form.length.$error.float">This is not a valid float number!</span></div></form></div></body></html>上面的例子中,我们创建了两个指令。
- 第一个指令是要验证输入的是否是整数。例如,1.23就不符合验证的值,因为它包含了分数部分。
- 第二个指令是要验证输入的是否是“智能浮点(smart-float)”。它能把"1.2"或者"1,2"都转化为合法的浮点数"1.2"。注意,这里我们不能使用input元素的type="number",因为支持HTML5的浏览器不允许用户输入像"1,2"这样的非法值。
AngularJS已经实现了所有基本的HTML表单控件(input,select,textarea),对于大部分情况应该已经够了。但是,你还是可以通过写指令来实现你自己的表单控件。要和ngModel指令协同工作实现自定义控件,并且实现双向绑定的话,需要:
- 实现render方法。这个方法负责在数据模型变化时,把变化的值传递给NgModelController#$formatters后,用来在view上渲染新的数据。
- 在用户与控件交互并且模型需要被更新时,调用$setViewValue方法。这通常是在DOM的监听事件中完成的。
下面的例子演示了如何添加一个“内容可编辑”的数据双向绑定的元素。 <!doctype html><html ng-app="form-example2"><head><script src="http://code.angularjs.org/angular-1.0.2.min.js"></script><script> angular.module("form-example2", []).directive("contenteditable", function() { //自定义指令contenteditable return { require: "ngModel", link: function(scope, elm, attrs, ctrl) { // view -> model elm.bind("blur", function() { //给元素div绑定blur事件 scope.$apply(function() { ctrl.$setViewValue(elm.html()); //当输入结束后,焦点离开div元素时,就更新model }); }); // model -> view ctrl.$render = function(value) { elm.html(value);//更新视图view }; // load init value from DOM ctrl.$setViewValue(elm.html()); } }; });</script></head><body><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></body></html>AngularJS权威教程 清晰PDF版 http://www.linuxidc.com/Linux/2015-01/111429.htm希望你喜欢,并分享我的工作~
带你走近AngularJS系列:
- 带你走近AngularJS - 基本功能介绍 http://www.linuxidc.com/Linux/2014-05/102140.htm
- 带你走近AngularJS - 体验指令实例 http://www.linuxidc.com/Linux/2014-05/102141.htm
- 带你走近AngularJS - 创建自定义指令 http://www.linuxidc.com/Linux/2014-05/102142.htm
如何在 AngularJS 中对控制器进行单元测试 http://www.linuxidc.com/Linux/2013-12/94166.htm在 AngularJS 应用中通过 JSON 文件来设置状态 http://www.linuxidc.com/Linux/2014-07/104083.htmAngularJS 之 Factory vs Service vs Provider http://www.linuxidc.com/Linux/2014-05/101475.htmAngularJS —— 使用 ngResource、RESTful APIs 和 Spring MVC 框架提交数据 http://www.linuxidc.com/Linux/2014-07/104402.htm
AngularJS 的详细介绍:请点这里
AngularJS 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-01/112574.htm