表单控件(input, select, textarea )是用来获取用户输入的。表单则是一组有联系的表单控件的集合。

用户能通过表单和表单控件提供验证的服务,知道自己的输入是否合法。这样能让用户交互变得友好,因为用户能通过反馈来修正自己的错误。不过,虽然客户端的验证能够起到很大作用,但也很容易被绕过,所以不能完全依靠客户端验证。 要建立安全的应用,服务器端验证还是必不可少的。

了解AngularJS双向绑定的关键在于了解ngModel指令。这个指令通过动态将model和view互相映射,来实现双向绑定。

为了能美化表单和表单元素,ngModel指令会自动为元素添加以下css类:

  • ng-valid
  • ng-invalid
  • ng-pristine
  • ng-dirty

一个表单就是一个FormController的实例,表单实例可以通过name属性选择性地公开到作用域中。同样的,一个表单控件也是一个NgModelController的实例,表单控件也能同样的被公开到作用域中。这意味视图能通过绑定的基本功能获取表单或者表单控件的状态。

  • 只有当表单发生改变时,重置按钮才会被显示出来。
  • 只有当表单有改变并且改变的值都是合法的,保存按钮才会被显示出来。
  • 能自定义user.email和user.agree的错误信息。

举个例子:

  1. <!doctype html>
  2. <html ng-app>
  3. <head>
  4. <script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
  5. <script>
  6. function Controller($scope) {
  7.       $scope.master= {};
  8.       $scope.update = function(user) {
  9.         $scope.master= angular.copy(user);
  10.       };
  11.       $scope.reset = function() {
  12.         $scope.user = angular.copy($scope.master);
  13.       };
  14.       $scope.isUnchanged = function(user) {
  15.         return angular.equals(user, $scope.master);
  16.       };
  17.       $scope.reset();
  18.     }
  19. </script>
  20. </head>
  21. <body>
  22. <div ng-controller="Controller">
  23. <form name="form" class="css-form" novalidate> //novalidate是用来屏蔽浏览器本身的验证功能的。
  24. Name:
  25. <input type="text" ng-model="user.name" name="uName" required /><br /> //required,此输入框必须有内容
  26. E-mail:
  27. <input type="email" ng-model="user.email" name="uEmail" required/><br />
  28. <div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">Invalid: //此div,如果form表中的name为uEmail的input元素中的内容违法或者是脏数据,那么就显示出来。
  29. <span ng-show="form.uEmail.$error.required">Tell us your email.</span> //如果错误信息是由required引起的,就显示此span
  30. <span ng-show="form.uEmail.$error.email">This is not a valid email.</span> //如果错误信息是由里面的内容不合法引起的,就显示此span
  31. </div>
  32.  
  33. Gender: <input type="radio" ng-model="user.gender" value="male" />male
  34. <input type="radio" ng-model="user.gender" value="female" />female<br />
  35.  
  36. <input type="checkbox" ng-model="user.agree" name="userAgree" required />
  37. I agree: <input ng-show="user.agree" type="text" ng-model="user.agreeSign"
  38. required /><br />
  39. <div ng-show="!user.agree || !user.agreeSign">Please agree and sign.</div>
  40.  
  41. <button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button>
  42. <button ng-click="update(user)" ng-disabled="form.$invalid || isUnchanged(user)">SAVE</button> //如果整个form表单没有通过验证或者form表单中的内容没有发生改变,此按钮就不可点击
  43. </form>
  44. </div>
  45. </body>
  46. </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来改变表单的验证状态。下面的例子,使用的是这个。

举个例子:

  1. <!doctype html>
  2. <html ng-app="form-example1">
  3. <head>
  4. <script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
  5. <script>
  6.   var app = angular.module('form-example1', []);
  7.       var INTEGER_REGEXP = /^\-?\d+$/; //或者以"-"(负)开头,或者没有负号,后面都是正整数,包括0
  8.       app.directive('integer', function() {
  9.        return {
  10.         require: 'ngModel', //依赖nogModel指令
  11.         link: function(scope, elm, attrs, ctrl) {
  12.           ctrl.$parsers.unshift(function(viewValue) { //ctrl可以调用ngModel指令中controller函数中定义的方法
  13.             if (INTEGER_REGEXP.test(viewValue)) {
  14.               ctrl.$setValidity('integer', true);
  15.               return viewValue;
  16.             } else {
  17.               ctrl.$setValidity('integer', false);
  18.               return undefined;
  19.             }
  20.           });
  21.         }
  22.        };
  23.       });
  24.       var FLOAT_REGEXP = /^\-?\d+((\.|\,)\d+)?$/; //可以是正负,可以是整数,也可以是浮点数,浮点数可以用"."分开,也可以用","分开。
  25.       app.directive('smartFloat', function() {
  26.        return {
  27.         require: 'ngModel',
  28.         link: function(scope, elm, attrs, ctrl) {
  29.           ctrl.$parsers.unshift(function(viewValue) {
  30.             if (FLOAT_REGEXP.test(viewValue)) {
  31.               ctrl.$setValidity('float', true);
  32.               return parseFloat(viewValue.replace(',', '.'));
  33.             } else {
  34.               ctrl.$setValidity('float', false);
  35.               return undefined;
  36.             }
  37.           });
  38.         }
  39.        };
  40.       });
  41. </script>
  42. </head>
  43. <body>
  44. <div ng-controller="Controller">
  45. <form name="form" class="css-form" novalidate>
  46. <div>
  47. Size (integer 0 - 10):
  48. <input type="number" ng-model="size" name="size" min="0" max="10" integer />{{size}}<br /> //integer,自定义指令
  49. <span ng-show="form.size.$error.integer">This is not valid integer!</span>
  50. <span ng-show="form.size.$error.min || form.size.$error.max">The value must be in range 0 to 10!</span>
  51. </div>
  52.  
  53. <div>
  54. Length (float):
  55. <input type="text" ng-model="length" name="length" smart-float />{{length}}<br /> //smart-float,自定义指令
  1. <span ng-show="form.length.$error.float">This is not a valid float number!</span>
  2. </div>
  3. </form>
  4. </div>
  5. </body>
  6. </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的监听事件中完成的。

下面的例子演示了如何添加一个“内容可编辑”的数据双向绑定的元素。

  1. <!doctype html>
  2. <html ng-app="form-example2">
  3. <head>
  4. <script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
  5. <script>
  6. angular.module('form-example2', []).directive('contenteditable', function() { //自定义指令contenteditable
  7.       return {
  8.         require: 'ngModel',
  9.         link: function(scope, elm, attrs, ctrl) {
  10.            // view -> model
  11.           elm.bind('blur', function() { //给元素div绑定blur事件
  12.            scope.$apply(function() {
  13.             ctrl.$setViewValue(elm.html()); //当输入结束后,焦点离开div元素时,就更新model
  14.            });
  15.           });
  16.           // model -> view
  17.           ctrl.$render = function(value) {
  18.             elm.html(value); //更新视图view
  19.           };
  20.           // load init value from DOM
  21.           ctrl.$setViewValue(elm.html());
  22.         }
  23.       };
  24.     });
  25. </script>
  26. </head>
  27. <body>
  28. <div contentEditable="true" ng-model="content" title="Click to edit">Some</div>
  29. <pre>model = {{content}}</pre>
  30. <style type="text/css">
  31. div[contentEditable] {
  32. cursor: pointer;
  33. background-color: #D0D0D0;
  34. }
  35. </style>
  36. </body>
  37. </html>

加油!

AngularJS开发指南6:AngularJS表单详解的更多相关文章

  1. AngularJS开发指南4:指令的详解

    指令是我们用来扩展浏览器能力的技术之一.在DOM编译期间,和HTML元素关联着的指令会被检测到,并且被执行.这使得指令可以为DOM指定行为,或者改变它. AngularJS有一套完整的.可扩展的.用来 ...

  2. Django学习笔记之Django Form表单详解

    知识预览 构建一个表单 在Django 中构建一个表单 Django Form 类详解 使用表单模板 回到顶部 构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的 ...

  3. Django之form表单详解

    构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的模板: <form action="/your-name/" method=" ...

  4. vue表单详解——小白速会

    一.基本用法 你可以用 v-model 指令在表单 <input> 及 <textarea> 元素上创建双向数据绑定. 但 v-model 本质上不过是语法糖.它负责监听用户的 ...

  5. HTNL表单详解

    HTML表单 表单的结构 表单的标签:<form> </form> 常用属性 Name , method(get,post), action(服务器的接收的页面如:reg.ph ...

  6. 移动IM开发指南2:心跳指令详解

    <移动IM开发指南>系列文章将会介绍一个IM APP的方方面面,包括技术选型.登陆优化等.此外,本文作者会结合他在网易云信多年iOS IM SDK开发的经验,深度分析实际开发中的各种常见问 ...

  7. form表单详解

    form表单 form是一个复杂的系统标签,其内部又可包含很多的一些输入标签 例如input 输入文本标签  checkbox 多选标签等等 form表单有几个属性我们需要注意一下 1:action属 ...

  8. 七、React表单详解 约束性和非约束性组件 input text checkbox radio select textarea 以及获取表单的内容

    一.约束性和非约束性组件: 非约束性组: MV: <input type="text" defaultValue="a" /> 这个 default ...

  9. HTTP头部POST表单详解

    2 POST /hello/checkUser.html?opt=xxx HTTP/1.1 方法的声明,Get,Post,Delete等 3 Accept: */* 4 Referer: http:/ ...

随机推荐

  1. vs安装mvc

    需要一个MVC框架和SP1补丁包,SP1补丁包的下载地址为:http://www.microsoft.com/downloads/details.aspx?FamilyID=27673c47-b3b5 ...

  2. ubuntu更新删除旧内核的shell脚本

    ubuntu经常提示要更新内核,更新几次后 /boot目录就满了,再更新就提示目录没空间了,这时候就需要删除不用的老旧内核,之前都是uname, grep, dpkg之类的命令一条条敲,然后用眼睛看需 ...

  3. linux command intro2 vi

    vi cusor : 0 : to the beginning of the current line $ : to the end of the current line G : to the la ...

  4. 如何快速开发出一个高质量的APP——创业谈

    [起] 今早,一个技术群里有人想快速做出一个app,然后询问技术方案,大概是这样, 拿到了200w投资,期望花20w两个月先做出一个app,包括iOS,Android, 先,呵呵,一下, 大概预估了一 ...

  5. [ubuntu]deb软件源

    虽然ubuntu的中国服务器的速度已经非常不错,但是难免,会有网络不畅的情形,所以修改软件源地址是一个基础的知识点. 修改ubuntu的软件源的方式有多种,一直是通过ubuntu软件中心提供的UI,还 ...

  6. 第24章 SEH结构化异常处理_异常处理及软件异常

    24.1  程序的结构 (1)try/except框架 __try{ //被保护的代码块 …… } __except(except fileter/*异常过滤程序*/){ //异常处理程序 } (2) ...

  7. Android Studio系列教程五--Gradle命令详解与导入第三方包

    Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...

  8. ClickJacking(点击劫持)

    问题: 点击劫持(ClickJacking)是一种视觉上的欺骗手段.大概有两种方式,一是攻击者使用一个透明的iframe,覆盖在一个网页上,然后诱使用户在该页面上进行操作,此时用户将在不知情的情况下点 ...

  9. Linux下检测IP地址冲突及解决方法

    问题说明:在公司办公网内的一台物理机A上安装了linux系统(ip:192.168.9.120),在上面部署了jenkins,redmine,svn程序.由于是在办公网内,这台机器和同事电脑都是在同一 ...

  10. Linux下smokeping网络监控环境部署记录

    smokeping是一款监控网络状态和稳定性的开源软件(它是rrdtool的作者开发的),通过它可以监控到公司IDC的网络状况,如延时,丢包率,是否BGP多线等:smokeping会向目标设备和系统发 ...