一般来讲表单可能遇到的问题:
1.如何数据绑定。
2.验证表单。
3.显示出错信息。
4.整个form的验证。
5.避免提交没有验证通过的表单。
6.防止多系提交。

input属性:
name
ng-model
ng-required
ng-minlength
ng-maxlength
ng-pattern
ng-change值变化时的回调

{{myForm.username.$error}}

Form控制变量
字段是否未更改
formName.inputFieldName.$pristine
字段是否更改
formName.inputFieldName.$dirty
字段有效
formName.inputFieldName.$valid
字段无效
formName.inputFieldName.$invalid
字段错误信息
formName.inputfieldName.$error

一个简单的表格的输入框的判断

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <link rel="stylesheet" href="../../vendor/bootstrap3/css/bootstrap.min.css"/>
  6. </head>
  7. <body>
  8. <div ng-app="myApp" style="margin-top: 100px;">
  9.  
  10. <form name="myForm" action="kittencup.php" ng-controller="firstController" class="container form-horizontal">
  11. <div class="form-group" ng-class="{'has-error':myForm.username.$dirty && myForm.username.$invalid}">
  12. <label class="col-sm-2 control-label">用户名</label>
  13. <div class="col-sm-10">
  14. <input type="text" autocomplete="off" name="username" ng-pattern="/^[a-zA-Z]{1}/" ng-required="true" ng-minlength="5" ng-maxlength="10" ng-model="data.username" class="form-control" placeholder="用户名">
  15. <div ng-show="myForm.username.$dirty && myForm.username.$error.maxlength" class="alert alert-danger help-block">
  16. 用户名长度不能超过10位
  17. </div>
  18. <div ng-show="myForm.username.$dirty && myForm.username.$error.minlength" class="alert alert-danger help-block">
  19. 用户名长度不能小于5位
  20. </div>
  21. <div ng-show="myForm.username.$dirty && myForm.username.$error.pattern" class="alert alert-danger help-block">
  22. 用户名必须已英文字母开始
  23. </div>
  24. </div>
  25. </div>
  26.  
  27. <div class="form-group" ng-class="{'has-error':myForm.password.$dirty && myForm.password.$invalid}">
  28. <label class="col-sm-2 control-label">密 码</label>
  29. <div class="col-sm-10">
  30. <input type="password" autocomplete="off" name="password" ng-required="true" ng-minlength="5" ng-maxlength="10" ng-model="data.password" class="form-control" placeholder="密码">
  31. <div ng-show="myForm.password.$dirty && myForm.password.$error.maxlength" class="alert alert-danger help-block">
  32. 密码长度不能超过10位
  33. </div>
  34. <div ng-show="myForm.password.$dirty && myForm.password.$error.minlength" class="alert alert-danger help-block">
  35. 密码长度不能小于5位
  36. </div>
  37. </div>
  38. </div>
  39.  
  40. <div class="form-group" ng-class="{'has-error':myForm.passwordConfirm.$dirty && myForm.passwordConfirm.$invalid}">
  41. <label class="col-sm-2 control-label">确认密码</label>
  42. <div class="col-sm-10">
  43. <input type="password" autocomplete="off" name="passwordConfirm" ng-required="true" ng-model="data.passwordConfirm" class="form-control" placeholder="确认密码">
  44. <div ng-show="myForm.password.$dirty && myForm.passwordConfirm.$dirty && data.password !== data.passwordConfirm" class="alert alert-danger help-block">
  45. 密码和确认密码不一致
  46. </div>
  47. </div>
  48. </div>
  49.  
  50. <div class="form-group" ng-class="{'has-error':myForm.email.$dirty && myForm.email.$invalid}">
  51. <label class="col-sm-2 control-label">邮箱</label>
  52. <div class="col-sm-10">
  53. <input type="email" autocomplete="off" name="email" ng-required="true" ng-minlength="5" ng-maxlength="30" ng-model="data.email" class="form-control" placeholder="邮箱">
  54. <div ng-show="myForm.email.$dirty && myForm.email.$error.maxlength" class="alert alert-danger help-block">
  55. 邮箱长度不能超过30位
  56. </div>
  57. <div ng-show="myForm.email.$dirty && myForm.email.$error.minlength" class="alert alert-danger help-block">
  58. 邮箱长度不能小于5位
  59. </div>
  60. <div ng-show="myForm.email.$dirty && myForm.email.$error.email" class="alert alert-danger help-block">
  61. 邮箱格式不正确
  62. </div>
  63. </div>
  64. </div>
  65.  
  66. <div class="form-group" ng-class="{'has-error':myForm.blog.$dirty && myForm.blog.$invalid}">
  67. <label class="col-sm-2 control-label">博客网址</label>
  68. <div class="col-sm-10">
  69. <input type="url" autocomplete="off" name="blog" ng-required="true" ng-minlength="5" ng-maxlength="30" ng-model="data.blog" class="form-control" placeholder="博客网址">
  70. <div ng-show="myForm.blog.$dirty && myForm.blog.$error.maxlength" class="alert alert-danger help-block">
  71. 网址长度不能超过30位
  72. </div>
  73. <div ng-show="myForm.blog.$dirty && myForm.blog.$error.minlength" class="alert alert-danger help-block">
  74. 网址长度不能小于5位
  75. </div>
  76. <div ng-show="myForm.blog.$dirty && myForm.blog.$error.url" class="alert alert-danger help-block">
  77. 网址格式不正确
  78. </div>
  79. </div>
  80. </div>
  81.  
  82. <div class="form-group" ng-class="{'has-error':myForm.age.$dirty && myForm.age.$invalid}">
  83. <label class="col-sm-2 control-label">年龄</label>
  84. <div class="col-sm-10">
  85. <input type="number" autocomplete="off" name="age" min="10" max="99" ng-required="true" ng-model="data.age" class="form-control" placeholder="年龄">
  86. <div ng-show="myForm.age.$dirty && myForm.age.$error.max" class="alert alert-danger help-block">
  87. 年龄不能超过99岁
  88. </div>
  89. <div ng-show="myForm.age.$dirty && myForm.age.$error.min" class="alert alert-danger help-block">
  90. 年龄不能小于10岁
  91. </div>
  92. </div>
  93. </div>
  94.  
  95. <div class="form-group">
  96. <label class="col-sm-2 control-label">性别</label>
  97. <div class="col-sm-10">
  98. <label class="radio-inline">
  99. <input type="radio" ng-required="true" name="sex" ng-model="data.sex" value="1" />
  100. </label>
  101. <label class="radio-inline">
  102. <input type="radio" ng-required="true" name="sex" ng-model="data.sex" value="0" />
  103. </label>
  104. </div>
  105. </div>
  106.  
  107. <div class="form-group">
  108. <label class="col-sm-2 control-label">爱好</label>
  109. <div class="col-sm-10">
  110. <label class="checkbox-inline" ng-repeat="hobby in hobbies">
  111. <input type="checkbox" ng-model="hobby.checked" name="hobby[]" ng-checked="data.hobbies === undefined ? false : data.hobbies.indexOf(hobby.id) !== -1" ng-click="toggleHobbySelection(hobby.id)"/> {{hobby.name}}
  112. </label>
  113. </div>
  114. </div>
  115.  
  116. <div class="form-group">
  117. <label class="col-sm-2 control-label">出生地</label>
  118. <div class="col-sm-3">
  119. <select class="form-control" ng-change="data.area = false" ng-model="data.province" ng-options="x.id as x.name for x in cities | cityFilter:0"></select>
  120. </div>
  121. <div class="col-sm-3">
  122. <select class="form-control" ng-show="data.province" ng-model="data.area" ng-options="x.id as x.name for x in cities | cityFilter:data.province"></select>
  123. </div>
  124. <div class="col-sm-3">
  125. <select class="form-control" ng-required="true" ng-show="data.province && data.area" ng-model="data.city" ng-options="x.id as x.name for x in cities | cityFilter:data.area"></select>
  126. </div>
  127. </div>
  128.  
  129. <div class="form-group">
  130. <label class="col-sm-2 control-label">只能输入偶数</label>
  131. <div class="col-sm-10">
  132. <input type="text" name="even" class="form-group" placeholder="偶数" ng-model="data.even" even>
  133. <div ng-show="myForm.even.$error.even" class="alert alert-danger help-block">
  134. 数字必须是偶数
  135. </div>
  136. </div>
  137. </div>
  138.  
  139. <div class="form-group">
  140. <label class="col-sm-2 control-label">个人介绍</label>
  141. <div class="col-sm-10">
  142. <custom-text-area ng-model="data.introduct">aaa</custom-text-area>
  143. <custom-text-area ng-model="data.introduct"></custom-text-area>
  144. </div>
  145. </div>
  146.  
  147. <div class="form-group">
  148. <div class="col-sm-offset-2 col-sm-10">
  149. <button type="submit" class="btn btn-default" ng-disabled="myForm.$invalid || data.hobbies === undefined || data.hobbies.length === 0">注册</button>
  150. <button type="reset" class="btn btn-default" ng-click="reset()">重置</button>
  151. </div>
  152.  
  153. </div>
  154.  
  155. </form>
  156.  
  157. </div>
  158.  
  159. <script type="text/javascript" src="../../vendor/angular/angularjs.js"></script>
  160. <script type="text/javascript" src="app/index.js"></script>
  161.  
  162. </body>
  163. </html>
  1. angular.module('myApp', [])
  2.  
  3. .filter('cityFilter', function () {
  4. return function (data, parent) {
  5. var filterData = [];
  6. angular.forEach(data, function (obj) {
  7. if (obj.parent === parent) {
  8. filterData.push(obj);
  9. }
  10. })
  11.  
  12. return filterData;
  13. }
  14. })
  15.  
  16. .directive('even',function(){
  17. return {
  18. require : 'ngModel',
  19. link:function(scope,elm,attrs,ngModelController){
  20. ngModelController.$parsers.push(function(viewValue){
  21. if(viewValue % 2 === 0){
  22. ngModelController.$setValidity('even',true);
  23. }else{
  24. ngModelController.$setValidity('even',false);
  25. }
  26. return viewValue;
  27. });
  28.  
  29. // ngModelController.$formatters.push(function(modelValue){
  30. // return modelValue + 'kittencup';
  31. // })
  32. }
  33. };
  34. })
  35.  
  36. .directive('customTextArea',function(){
  37. return {
  38. restrict:'E',
  39. template:'<div contenteditable="true"></div>',
  40. replace:true,
  41. require : 'ngModel',
  42. link:function(scope,elm,attrs,ngModelController){
  43.  
  44. // view->model
  45. elm.on('keyup',function(){
  46. scope.$apply(function(){
  47. ngModelController.$setViewValue(elm.html());
  48. });
  49. })
  50.  
  51. ngModelController.$render = function(){
  52. elm.html(ngModelController.$viewValue);
  53. }
  54.  
  55. }
  56. };
  57. })
  58.  
  59. .controller('firstController', ['$scope', function ($scope) {
  60.  
  61. var that = this;
  62.  
  63. $scope.hobbies = [
  64. {
  65. id: 1,
  66. name: '玩游戏'
  67. },
  68. {
  69. id: 2,
  70. name: '写代码'
  71. },
  72. {
  73. id: 3,
  74. name: '睡觉'
  75. },
  76. ];
  77.  
  78. $scope.cities = [
  79. {
  80. name: '上海',
  81. parent: 0,
  82. id: 1
  83. },
  84. {
  85. name: '上海市',
  86. parent: 1,
  87. id: 2
  88. },
  89. {
  90. name: '徐汇区',
  91. parent: 2,
  92. id: 8
  93. },
  94. {
  95. name: '长宁区',
  96. parent: 2,
  97. id: 3
  98. },
  99. {
  100. name: '北京',
  101. parent: 0,
  102. id: 4
  103. },
  104. {
  105. name: '北京市',
  106. parent: 4,
  107. id: 5
  108. },
  109. {
  110. name: '东城区',
  111. parent: 5,
  112. id: 6
  113. },
  114. {
  115. name: '丰台区',
  116. parent: 5,
  117. id: 7
  118. },
  119. {
  120. name: '浙江',
  121. parent: 0,
  122. id: 9
  123. },
  124. {
  125. name: '杭州',
  126. parent: 9,
  127. id: 100
  128. },
  129. {
  130. name: '宁波',
  131. parent: 9,
  132. id: 11
  133. },
  134. {
  135. name: '西湖区',
  136. parent: 100,
  137. id: 12
  138. },
  139. {
  140. name: '北仑区‎',
  141. parent: 11,
  142. id: 13
  143. }
  144. ];
  145.  
  146. $scope.data = {
  147. hobbies: [1, 2],
  148. city: 3
  149. };
  150.  
  151. // 先保留一份默认值
  152. $scope.origData = angular.copy($scope.data);
  153.  
  154. $scope.reset = function(){
  155.  
  156. $scope.data = angular.copy($scope.origData);
  157. that.initCity();
  158. $scope.myForm.$setPristine();
  159. }
  160.  
  161. // 让城市关联使用
  162. this.findCityId = function (parent) {
  163. var parentId;
  164. angular.forEach($scope.cities, function (city) {
  165. if (city.id === parent) {
  166. parentId = city.parent;
  167. return;
  168. }
  169. })
  170.  
  171. return parentId;
  172. }
  173.  
  174. this.initCity = function(){
  175. if ($scope.data.city !== undefined) {
  176. $scope.data.area = this.findCityId($scope.data.city);
  177. $scope.data.province = this.findCityId($scope.data.area);
  178. }
  179. }
  180.  
  181. // 第一次打开页面 需要初始化一下
  182. this.initCity.call(this);
  183.  
  184. $scope.toggleHobbySelection = function (id) {
  185.  
  186. var index = -1;
  187. if ($scope.data.hobbies === undefined) {
  188. $scope.data.hobbies = [];
  189. } else {
  190. index = $scope.data.hobbies.indexOf(id);
  191. }
  192.  
  193. if (index === -1) {
  194. $scope.data.hobbies.push(id);
  195. } else {
  196. $scope.data.hobbies.splice(index, 1);
  197. }
  198.  
  199. }
  200. }]);

===========================================

myForm.username.$dirty  如果表单有更改则为true,如果没有更改则为false。

myForm.username.$error.maxlength 如果超出则为true,如果没有超出则为false。

ng-class="{'has-error':myForm.password.$dirty && myForm.password.$invalid}" 这句的意思是为了可以让写错后,边框变红。

autocomplete="off"  关闭自动提示的功能

ng-options="x.id as x.name for x in cities | cityFilter:0" 看链接:http://each.sinaapp.com/angular/tutorial/ng-options.html

ng-model 是angular原生的directive
可以通过require ngModel可以更深入的去处理数据的双向绑定。
ngModel里的属性

$parsers属性,保存了从viewValue向modelValue绑定过程中的处理函数,它们将来会依次执行。
$formatters它保存的是从modelValue向viewValue绑定过程中的处理函数
$setViewValue 当view发生了某件事情时,从view向model绑定调用
$setViewValue
$render
$setValidity
$viewValue
$modelValue

当reset的按钮同时又click事件时,先执行本身的reset然后执行click事件。

注意表单中这几个位置的写法,ng-model必须是$scope中给出的,不能写user.

angular的 表单的更多相关文章

  1. angular js 表单验证

    <!doctype html> <html ng-app="myapp"> <head> <meta charset="UTF- ...

  2. angular编写表单验证

    angular编写表单验证 一.整体概述 表单内容如下图,包括常用的用户名.密码.确认密码.手机.邮箱等 整体js代码很少,就一个指令用于写确认密码和密码是否相等.其他 验证都是使用angular自带 ...

  3. 关于angular实现表单的一些问题

    如何用angular实现表单的一些问题?核心步骤大概如下: 创建模型类 创建控制此表单的组件. 创建具有初始表单布局的模板. 使用ngModel双向数据绑定语法把数据属性绑定到每个表单输入控件. 往每 ...

  4. 使用Angular提交表单

    使用Angular提交表单 我们准备在之前使用的<script>标签中设置我们的Angular应用.所以删除里面的内容,我们就可以开始了. 设置一个Angular应用 步骤为: 1. 加载 ...

  5. Angular.js表单以及与Bootatrap的使用

    首先从angular.js的目录开始,如下图,知道了我们要学什么,然后再开始有目的的学习与对比. 1.从表达式开始: ng-app指令初始化一个 AngularJS 应用程序. ng-init指令初始 ...

  6. angular验证表单

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>a ...

  7. angular之表单验证与ngMessages

    刚接触angular1.x很多经常用到的ngMessages的地方,这里顺便记一下,效果如下图: 如果引用了angular-messages.js报如下错误,说明你的angular.js和angula ...

  8. Angular动态表单生成(八)

    动态表单生成之拖拽生成表单(下) 我们的动态表单,最终要实现的效果与Form.io的在线生成表单的效果类似,可以参考它的demo地址:https://codepen.io/travist/full/x ...

  9. Angular动态表单生成(七)

    动态表单生成之拖拽生成表单(上) 这个功能就比较吊炸天了,之前的六篇,都是ng-dynamic-forms自带的功能,可能很多的说明官方的文档都已经写了,我只是个搬运工,而在这篇文章中,我将化身一个工 ...

随机推荐

  1. Oracle Database Memory Structures

    Oracle Database creates and uses memory structures for various purposes. For example, memory stores ...

  2. mysql常见的错误码

    Mysql错误代码 Mysql错误代码分为两部分,老版本一部分,4.1版本为新的部分 第一部分: mysql的出错代码表,根据mysql的头文件mysql/include/mysqld_error.h ...

  3. Zend_Framework_1 框架是如何被启动的?

    Zend Framework 1 是一个十年前的老框架了,我接触它也有两年了,现在来写这篇文章,主要原因是最近要写入职培训教程.公司项目基本上都是基于Zend1框架,即使现在要转 Laravel 也肯 ...

  4. CH0601 Genius ACM【倍增】【归并排序】

    0601 Genius ACM 0x00「基本算法」例题 描述 给定一个整数 M,对于任意一个整数集合 S,定义“校验值”如下: 从集合 S 中取出 M 对数(即 2∗M 个数,不能重复使用集合中的数 ...

  5. 使用colmap进行稠密重建

    colmap应该是目前state-of-art的增量式SFM方案,可以方便的对一系列二维图片进行三维重建 不用对摄像机进行标定,只需要从不同角度对重建场景或物体进行拍摄得到一系列图像作为输入 首先需要 ...

  6. java 获取当前进程id 线程id

    java  获取当前进程id  线程id RuntimeMXBean (Java Platform SE 8 ) https://docs.oracle.com/javase/8/docs/api/j ...

  7. Dolls---hdu4160(最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4160 有n个长方体形的娃娃:当长宽高都小于另一个的时候可以放进去,每一个里面最多放一个,问最优的套法下 ...

  8. django的crontab

    最近需要考虑如何在django环境中跑定时任务. 这个在  stackoverflow 也有对应的 讨论 , 方法也有不少, 这边简单尝试和总结下. 假设我们现在的定期任务就是睡眠  n 秒, 然后往 ...

  9. 解决redis远程连接不上的问题

    解决redis远程连接不上的问题 redis现在的版本开启redis-server后,redis-cli只能访问到127.0.0.1,因为在配置文件中固定了ip,因此需要修改redis.conf(有的 ...

  10. PyCharm安装与配置,python的Hello World

    1. 访问https://www.jetbrains.com/zh/pycharm/download/download-thanks.html, 下载pycharm 安 装包,点击安装. 2. 用记事 ...