当前位置:Gxlcms > JavaScript > 关于AngularJsForms的解析

关于AngularJsForms的解析

时间:2021-07-01 10:21:17 帮助过:9人阅读

本文主要介绍AngularJs Forms,这里整理了相关资料及简单示例代码,有需要的朋友可以参考下

控件(input、select、textarea)是用户输入数据的一种方式。Form(表单)是这些控件的集合,目的是将相关的控件进行分组。

  表单和控件提供了验证服务,所以用户可以收到无效输入的提示。这提供了更好的用户体验,因为用户可以立即获取到反馈,知道如何修正错误。请记住,虽然客户端验证在提供良好的用户体验中扮演重要的角色,但是它可以很简单地被绕过,因此,客户端验证是不可信的。服务端验证对于一个安全的应用来说仍然是必要的。

一、Simple form

  理解双向数据绑定的关键directive是ngModel。ngModel提供了从model到view和view到model的双向数据绑定。并且,它还向其他directive提供API,增强它们的行为。

  1. <!DOCTYPE HTML>
  2. <html lang="zh-cn" ng-app="SimpleForm">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>PropertyEvaluation</title>
  6. <style type="text/css">
  7. .ng-cloak {
  8. display: none;
  9. }
  10. </style>
  11. </head>
  12. <body>
  13. <p ng-controller="MyCtrl" class="ng-cloak">
  14. <form novalidate>
  15. 名字: <input ng-model="user.name" type="text"><br/>
  16. Email: <input ng-model="user.email" type="email"><br/>
  17. 性别: <input value="男" ng-model="user.gender" type="radio">男
  18. <input value="女" ng-model="user.gender" type="radio">女
  19. <br/>
  20. <button ng-click="reset()">还原上次保存</button>
  21. <button ng-click="update(user)">保存</button>
  22. </form>
  23. <pre>form = {{user | json}}</pre>
  24. <pre>saved = {{saved | json}}</pre>
  25. </p>
  26. <script src="../angular-1.0.1.js" type="text/javascript"></script>
  27. <script type="text/javascript">
  28. var app = angular.module("SimpleForm", []);
  29. app.controller("MyCtrl", function ($scope,$window) {
  30. $scope.saved = {};
  31. $scope.update = function(user) {
  32. $scope.saved = angular.copy(user);
  33. };
  34. $scope.reset = function() {
  35. $scope.user = angular.copy($scope.saved);
  36. };
  37. $scope.reset();
  38. //不合法的值将不会进入user
  39. });
  40. </script>
  41. </body>
  42. </html>

二、Using CSS classes

  为了让form以及控件、ngModel富有样式,可以增加以下class:

  1. ng-valid

  2. ng-invalid

  3. ng-pristine(从未输入过)

  4. ng-dirty(输入过)

  下面的例子,使用CSS去显示每个表单控件的有效性。例子中,user.name和user.email都是必填的,但当它们修改过之后(dirty),背景将呈现红色。这确保用户不会直到与表单交互之后(提交之后?),发现未能满足其有效性,才为一个错误而分心。

  1. <!DOCTYPE HTML>
  2. <html lang="zh-cn" ng-app="CSSClasses">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>CSSClasses</title>
  6. <style type="text/css">
  7. .ng-cloak {
  8. display: none;
  9. }
  10. .css-form input.ng-invalid.ng-dirty {
  11. background-color: #fa787e;
  12. }
  13. .css-form input.ng-valid.ng-dirty {
  14. background-color: #78fa89;
  15. }
  16. </style>
  17. </head>
  18. <body>
  19. <p ng-controller="MyCtrl" class="ng-cloak">
  20. <form novalidate class="css-form" name="formName">
  21. 名字: <input ng-model="user.name" type="text" required><br/>
  22. Email: <input ng-model="user.email" type="email" required><br/>
  23. 性别: <input value="男" ng-model="user.gender" type="radio">男
  24. <input value="女" ng-model="user.gender" type="radio">女
  25. <br/>
  26. <button ng-click="reset()">RESET</button>
  27. <button ng-click="update(user)">SAVE</button>
  28. </form>
  29. <pre>form = {{user | json}}</pre>
  30. <pre>saved = {{saved | json}}</pre>
  31. </p>
  32. <script src="../angular-1.0.1.js" type="text/javascript"></script>
  33. <script type="text/javascript">
  34. var app = angular.module("CSSClasses", []);
  35. app.controller("MyCtrl", function ($scope,$window) {
  36. $scope.saved = {};
  37. $scope.update = function(user) {
  38. $scope.saved = angular.copy(user);
  39. };
  40. $scope.reset = function() {
  41. $scope.user = angular.copy($scope.saved);
  42. };
  43. $scope.reset();
  44. //不合法的值将不会进入user
  45. });
  46. </script>
  47. </body>
  48. </html>

三、Binding to form and control state

  在angular中,表单是FormController的一个实例。表单实例可以随意地使用name属性暴露到scope中(这里没看懂,scope里面没有一个跟form的name属性一直的property,但由于有“document.表单名”这种方式,所以还是可以获取到的)。相似地,控件是NgModelController的实例。控件实例可以相似地使用name属性暴露在form中。这说明form和控件(control)两者的内部属性对于使用标准绑定实体(standard binding primitives)绑定在视图中的这个做法是可行的。

  这允许我们通过以下特性来扩展上面的例子:

  1. RESET按钮仅仅在form发生改变之后才可用。

  2. SAVE按钮仅仅在form发生改变而且输入有效的情况下可用。

  3. 为user.email和user.agree定制错误信息。

  1. <!DOCTYPE HTML>
  2. <html lang="zh-cn" ng-app="ControlState">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>ControlState</title>
  6. <style type="text/css">
  7. .ng-cloak {
  8. display: none;
  9. }
  10. .css-form input.ng-invalid.ng-dirty {
  11. background-color: #fa787e;
  12. }
  13. .css-form input.ng-valid.ng-dirty {
  14. background-color: #78fa89;
  15. }
  16. </style>
  17. </head>
  18. <body>
  19. <p ng-controller="MyCtrl" class="ng-cloak">
  20. <form novalidate class="css-form" name="formName">
  21. 名字: <input ng-model="user.name" name="userName" type="text" required><br/>
  22. <p ng-show="formName.userName.$dirty&&formName.userName.$invalid">
  23. <span>请填写名字</span>
  24. </p>
  25. Email: <input ng-model="user.email" name="userEmail" type="email" required><br/>
  26. <p ng-show="formName.userEmail.$dirty && formName.userEmail.$invalid">提示:
  27. <span ng-show="formName.userEmail.$error.required">请填写Email</span>
  28. <span ng-show="formName.userEmail.$error.email">这不是一个有效的Email</span>
  29. </p>
  30. 性别: <input value="男" ng-model="user.gender" type="radio">男
  31. <input value="女" ng-model="user.gender" type="radio">女
  32. <br/>
  33. <input type="checkbox" ng-model="user.agree" name="userAgree" required/>我同意:
  34. <input type="text" ng-show="user.agree" ng-model="user.agreeSign" required/>
  35. <br/>
  36. <p ng-show="!formName.userAgree || !user.agreeSign">请同意并签名~</p>
  37. <button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button>
  38. <button ng-click="update(user)" ng-disabled="formName.$invalid || isUnchanged(user)">SAVE</button>
  39. </form>
  40. <pre>form = {{user | json}}</pre>
  41. <pre>saved = {{saved | json}}</pre>
  42. </p>
  43. <script src="../angular-1.0.1.js" type="text/javascript"></script>
  44. <script type="text/javascript">
  45. var app = angular.module("ControlState", []);
  46. app.controller("MyCtrl", function ($scope,$window) {
  47. $scope.saved = {};
  48. $scope.update = function(user) {
  49. $scope.saved = angular.copy(user);
  50. };
  51. $scope.reset = function() {
  52. $scope.user = angular.copy($scope.saved);
  53. };
  54. $scope.isUnchanged = function(user) {
  55. return angular.equals(user, $scope.saved);
  56. };
  57. $scope.reset();
  58. //不合法的值将不会进入user
  59. });
  60. </script>
  61. </body>
  62. </html>

四、Custom Validation

  angular为大多数公共的HTML表单域(input,text,number,url,email,radio,checkbox)类型提供了实现,也有一些为了表单验证的directive(required,pattern,,inlength,maxlength,min,max)。

  可以通过定义增加定制验证函数到ngModel controller(这里是连在一起的ngModelController吗?)中的directive来定义我们自己的验证插件。为了得到一个controller,directive如下面的例子那样指定了依赖(directive定义对象中的require属性)。

Model到View更新 - 无论什么时候Model发生改变,所有在ngModelController.$formatters(当model发生改变时触发数据有效性验证和格式化转换)数组中的function将排队执行,所以在这里的每一个function都有机会去格式化model的值,并且通过NgModelController.$setValidity(http://code.angularjs.org/1.0.2/docs/api/ng.directive:ngModel.NgModelController#$setValidity)修改控件的验证状态。

View到Model更新 - 一个相似的方式,无论任何时候,用户与一个控件发生交互,将会触发NgModelController.$setViewValue。这时候轮到执行NgModelController$parsers(当控件从DOM中取得值之后,将会执行这个数组中所有的方法,对值进行审查过滤或转换,也进行验证)数组中的所有方法。

  在下面的例子中我们将创建两个directive。

第一个是integer,它负责验证输入到底是不是一个有效的整数。例如1.23是一个非法的值,因为它包含小数部分。注意,我们通过在数组头部插入(unshift)来代替在尾部插入(push),这因为我们想它首先执行并使用这个控件的值(估计这个Array是当作队列来使用的),我们需要在转换发生之前执行验证函数。

第二个directive是smart-float。他将”1.2”和”1,2”转换为一个合法的浮点数”1.2”。注意,我们在这不可以使用HTML5的input类型”number”,因为浏览器不允许用户输入我们预期的非法字符,如”1,2”(它只认识”1.2”)。

  1. <!DOCTYPE HTML>
  2. <html lang="zh-cn" ng-app="CustomValidation">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>CustomValidation</title>
  6. <style type="text/css">
  7. .ng-cloak {
  8. display: none;
  9. }
  10. .css-form input.ng-invalid.ng-dirty {
  11. background-color: #fa787e;
  12. }
  13. .css-form input.ng-valid.ng-dirty {
  14. background-color: #78fa89;
  15. }
  16. </style>
  17. </head>
  18. <body>
  19. <p class="ng-cloak">
  20. <form novalidate class="css-form" name="formName">
  21. <p>
  22. 大小(整数 0 - 10):<input integer type="number" ng-model="size" name="size" min="0" max="10"/>{{size}}<br/>
  23. <span ng-show="formName.size.$error.integer">这不是一个有效的整数</span>
  24. <span ng-show="formName.size.$error.min || formName.size.$error.max">
  25. 数值必须在0到10之间
  26. </span>
  27. </p>
  28. <p>
  29. 长度(浮点数):
  30. <input type="text" ng-model="length" name="length" smart-float/>
  31. {{length}}<br/>
  32. <span ng-show="formName.length.0error.float">这不是一个有效的浮点数</span>
  33. </p>
  34. </form>
  35. </p>
  36. <script src="../angular-1.0.1.js" type="text/javascript"></script>
  37. <script type="text/javascript">
  38. var app = angular.module("CustomValidation", []);
  39. var INTEGER_REGEXP = /^\-?\d*$/;
  40. app.directive("integer", function () {
  41. return {
  42. require:"ngModel",//NgModelController
  43. link:function(scope,ele,attrs,ctrl) {
  44. ctrl.$parsers.unshift(function (viewValue) {//$parsers,View到Model的更新
  45. if(INTEGER_REGEXP.test(viewValue)) {
  46. //合格放心肉
  47. ctrl.$setValidity("integer", true);
  48. return viewValue;
  49. }else {
  50. //私宰肉……
  51. ctrl.$setValidity("integer", false);
  52. return undefined;
  53. }
  54. });
  55. }
  56. };
  57. });
  58. var FLOAT_REGEXP = /^\-?\d+(?:[.,]\d+)?$/;
  59. app.directive("smartFloat", function () {
  60. return {
  61. require:"ngModel",
  62. link:function(scope,ele,attrs,ctrl) {
  63. ctrl.$parsers.unshift(function(viewValue) {
  64. if(FLOAT_REGEXP.test(viewValue)) {
  65. ctrl.$setValidity("float", true);
  66. return parseFloat(viewValue.replace(",", "."));
  67. }else {
  68. ctrl.$setValidity("float", false);
  69. return undefined;
  70. }
  71. });
  72. }
  73. }
  74. });
  75. </script>
  76. </body>
  77. </html>

五、Implementing custom form control (using ngModel)

  angular实现了所有HTML的基础控件(input,select,textarea),能胜任大多数场景。然而,如果我们需要更加灵活,我们可以通过编写一个directive来实现自定义表单控件的目的。

  为了制定控件和ngModel一起工作,并且实现双向数据绑定,它需要:

实现render方法,是负责在执行完并通过所有NgModelController.$formatters方法后,呈现数据的方法。

调用$setViewValue方法,无论任何时候用户与控件发生交互,model需要进行响应的更新。这通常在DOM事件监听器里实现。
  可以查看$compileProvider.directive获取更多信息。

  下面的例子展示如何添加双向数据绑定特性到可以编辑的元素中。

  1. <!DOCTYPE HTML>
  2. <html lang="zh-cn" ng-app="CustomControl">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>CustomControl</title>
  6. <style type="text/css">
  7. .ng-cloak {
  8. display: none;
  9. }
  10. p[contenteditable] {
  11. cursor: pointer;
  12. background-color: #D0D0D0;
  13. }
  14. </style>
  15. </head>
  16. <body ng-controller="MyCtrl">
  17. <p class="ng-cloak">
  18. <p contenteditable="true" ng-model="content" title="点击后编辑">My Little Dada</p>
  19. <pre>model = {{content}}</pre>
  20. <button ng-click="reset()">reset model tirgger model to view($render)</button>
  21. </p>
  22. <script src="../angular-1.0.1.js" type="text/javascript"></script>
  23. <script type="text/javascript">
  24. var app = angular.module("CustomControl", []);
  25. app.controller("MyCtrl", function ($scope) {
  26. $scope.reset = function() {
  27. $scope.content = "My Little Dada";
  28. //在这里如何获取NgModelController呢?如果你们知道,希望可以指点指点!谢谢
  29. };
  30. });
  31. app.directive("contenteditable", function () {
  32. return {
  33. require:"ngModel",
  34. link:function (scope, ele, attrs, ctrl) {
  35. //view -> model
  36. ele.bind("blur keyup",function() {
  37. scope.$apply(function() {
  38. console.log("setViewValue");
  39. ctrl.$setViewValue(ele.text());
  40. });
  41. });
  42. //model -> view
  43. ctrl.$render = function(value) {
  44. console.log("render");
  45. ele.html(value);
  46. };
  47. //读取初始值
  48. ctrl.$setViewValue(ele.text());
  49. }
  50. };
  51. });
  52. </script>
  53. </body>
  54. </html>

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

关于Angular4 中内置指令的基本用法

在angularJs中如何实现清除浏览器缓存

在Angular2中有关自定义管道格式数据用法

以上就是关于AngularJs Forms的解析的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行