AngularJS 表单提交验证:$dirty、$valid 和 $invalid

AngularJS 中的表单验证
表格验证 在 AngularJS 中,验证是确保表单中输入的数据正确完整过程。用户提交表单后,在将数据发送到服务器之前,会先进行验证。验证过程旨在最大程度地确保输入字段已正确填写。
举个实际例子,假设某个网站要求用户填写注册表单才能获得完整访问权限。注册页面会有用户名、密码、邮箱地址等输入框。
例如,电子邮件地址必须始终采用以下格式: 用户名@站点.域名如果有人只输入用户名,验证应该失败。验证会在将详细信息发送到服务器进行进一步处理之前执行这些基本检查。
⚠️ 版本说明: AngularJS(1.x 分支)已于 2021 年 12 月 31 日停止维护,不再接收任何安全补丁。以下方法仍然适用于旧版应用程序;现代 Angular 使用模板驱动或响应式表单来处理相同的任务。
使用 HTML5 进行表单验证
表单验证是指在将网页表单发送到服务器之前,预先验证用户输入的信息。客户端验证更可取,因为它比往返服务器后重新提交表单的开销要小得多。
下面的示例展示了一个简单的注册表单,用户可以在其中输入用户名、密码、电子邮件地址和年龄。该表单包含验证控件,以确保信息输入正确。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Event Registration</title> <link rel="stylesheet" href="lib/bootstrap.css"> <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script> </head> <body ng-app="sampleApp"> <h1>Guru99 Global Event</h1> <form> Enter your user name: <input type="text" name="name" required><br><br> Enter your password: <input type="password" name="password"><br><br> Enter your email: <input type="email" name="email"><br><br> Enter your age: <input type="number" name="age"><br><br> <input type="submit" value="Submit"> </form> </body> </html>
⚠️ 本页面所有信息均已更正。 原件声明 chrset="UTF 8"这既不是有效的属性,也不是有效的编码,并且导致 AngularJS 加载了三次—— angular-route.js 首先,这会抛出异常,因为路由模块注册的框架尚未加载;然后 angular.min.js 和 angular.js他们两次使用了同一个图书馆。他们还提取了 bootstrap.css 通过 <script> 标签,因此从未应用任何样式。现在每个列表都加载一个库(版本 1.8.3),并正确链接样式表。布局内边距由重复元素构成。 实体已被移除。
Code 说明
- 对于文本输入类型,
required该属性表示表单提交时文本框不能为空。 - 下一个输入类型是密码。由于该类型被标记为密码,因此字段中输入的文本将被屏蔽。
- 由于输入类型指定为电子邮件,因此框中的文本必须与模式匹配。 名称@站点.域名.
- 当输入类型标记为数字时,该字段根本不接受从键盘输入的字符。
输出
要查看验证效果,请点击“提交”按钮,无需输入任何内容。
弹出窗口提示需要填写该字段,因此标记为必填的控件会在字段为空时阻止提交。
在密码控件中输入值时,会显示“*”符号来遮盖字符。
输入格式错误的电子邮件地址并点击“提交”后,会弹出窗口要求输入@符号。此外,在年龄字段中输入的字符不会显示,因为该字段只接受数字。
浏览器弹出窗口设置快捷,但其文字和样式无法更改。这时,AngularJS 的验证属性就派上了用场。
使用 $dirty、$valid、$invalid、$pristine 进行表单验证
AngularJS 它提供了用于验证的自身属性。以下属性在每个命名控件上都公开:
- $脏 – 用户已经与控件交互
- $有效 – 字段内容有效
- $无效 – 字段内容无效
- $原始 – 用户尚未与控件进行交互
以下是执行 AngularJS 验证的步骤。
步骤1) 使用 novalidate 声明表单时添加此属性。这会告诉浏览器验证将由 AngularJS 处理。
步骤2) 请确保表单已定义名称,因为该名称用于进入验证状态。
步骤3) 确保每个控件也都有 name 出于同样的原因,属性也需要进行设置。没有名称的控件永远不会在表单上注册。
步骤4) 使用 吴秀 指示检查 $dirty、$invalid 和 $valid 属性。
以下示例包含一个文本字段,供用户输入主题名称。如果该字段为空,则会触发验证错误并显示错误信息。
<form ng-app="DemoApp" ng-controller="DemoController" name="myForm" novalidate> <p>Topic Name:<br> <input type="text" name="user" ng-model="user" required> <span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid"> <span ng-show="myForm.user.$error.required">Username is required</span> </span> </p> <p> <input type="submit" ng-disabled="myForm.$invalid"> </p> </form> <script> var app = angular.module("DemoApp", []); app.controller("DemoController", function($scope) { // Seed the textbox so the form starts in a valid state $scope.user = "AngularJS"; }); </script>
⚠️ 已修正两处逻辑错误。 原先禁用了该按钮 ng-disabled="myForm.user.$dirty && myForm.user.$invalid"。 因为 $dirty 在用户触摸该字段之前,该值为假;按钮一直处于显示状态。 启用 在未经修改的空白表单上,正是它要阻止的情况; myForm.$invalid 两者都涵盖了。原版还将默认值封装在内。 $scope.Display = function () { $scope.user = 'Angular'; }这是一个从未被调用过的函数,因此尽管文本框显示“AngularJS”,但文本框打开时却是空的。现在直接赋值,值包含在周围文本的引号中。
Code 说明
- 表单被命名为“myForm”。这是为了能够访问其控件进行验证而必须的。
- 此
novalidate该属性会阻止浏览器进行验证,以便 AngularJS 可以代替浏览器进行验证。 - ng-show 指令会检查“$dirty”和“$invalid”属性。如果文本框已被修改,则 $dirty 为 true;如果文本框的值为空,则 $invalid 为 true。当这两个属性都为 true 时,将显示带有红色文本的 span 元素。
- 嵌套检查会读取“$error.required”属性,当必填控件没有值时,该属性为真,并显示“用户名是必填项”。
- 提交按钮已禁用
ng-disabled当整个表单无效时。 - 控制器将初始文本框值设置为“AngularJS”,因此表单以有效状态打开,并且在删除文本时更容易观察验证过程。
输出
表单首次显示时,文本框中会显示“AngularJS”,并且提交按钮处于启用状态。删除文本后,会显示错误信息,并且按钮会变为禁用状态。
上面的截图显示了两件事:
- 提交按钮已禁用
- “主题”文本框中没有主题名称,因此显示错误消息“需要用户名”。
如何使用 ngMessages 显示验证错误
上述模式可行,但无法扩展。一个包含四个约束的字段需要四个嵌套的约束。 ng-show 跨度,当多个跨度同时失效时,所有消息会同时出现。 ngMessages AngularJS 团队单独发布的模块解决了这两个问题:它一次显示一条消息,并按照消息的编写顺序显示。
加载模块并将其添加为依赖项。
<script src="https://code.angularjs.org/1.8.3/angular-messages.js"></script> <script> angular.module("DemoApp", ["ngMessages"]); </script>
这样一来,标记就变成了一系列规则,而不是一堆条件。
<input type="text" name="user" ng-model="user" required ng-minlength="4" ng-maxlength="20"> <div style="color:red" ng-messages="myForm.user.$error" ng-if="myForm.user.$dirty"> <div ng-message="required">A topic name is required</div> <div ng-message="minlength">Use at least 4 characters</div> <div ng-message="maxlength">Use no more than 20 characters</div> </div>
三个细节使得它在实践中表现良好。 ng-messages 属性指向控件的 $error 它返回的是一个对象而不是一个布尔值,因此无需重复条件。只需匹配第一个对象即可。 ng-message 渲染结果显示,即使字段为空,也会报告它是必填项,而不会因为字段长度不足而发出警告。添加 ng-messages-multiple 当确实需要列出所有失败案例时,这种做法就会发生逆转。
饺子皮ping 街区 ng-if="myForm.user.$dirty" 保持表单静默,直到用户实际输入内容。替换 $touched HPMC胶囊 $dirty 进一步延迟显示消息,直到焦点离开该字段,这在冗长的注册表单中通常是更友好的选择。
一个警告: ngMessages 由于它作为单独的文件发送,因此忘记脚本标签或模块依赖项会导致代码块完全不渲染任何内容,并且控制台不会出现任何错误来解释这种情况。
手写信息虽然精确,但很重复。下一节将介绍一个可以自动生成信息的模块。
使用 AngularJS Auto Validate 进行表单验证
AngularJS 可以自动验证表单上的所有控件,无需编写自定义验证代码或错误消息。这是通过引入名为“jcs-autoValidate”的社区模块实现的。
有了这个模块,就不需要特殊的代码来运行验证或显示消息;一切都在 jcs-autoValidate 内部处理。
下面的示例是一个简单的表单,其中包含一个必填文本框。如果该文本框未填写,则会显示错误消息。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Event Registration</title> <link rel="stylesheet" href="lib/bootstrap.css"> <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script> <script src="lib/jcs-auto-validate.min.js"></script> </head> <body> <h1>Guru99 Event</h1> <div ng-app="DemoApp"> <form name="myForm" novalidate> <div class="form-group"> <label for="user">Topic Name:</label> <input class="form-control" type="text" id="user" name="user" ng-model="user" required> </div> <div class="form-group"> <input type="submit"> </div> </form> </div> <script> var app = angular.module('DemoApp', ['jcs-autoValidate']); </script> </body> </html>
⚠️更正: 原图将对照组确定为 id="user" 仅此而已。jcs-autoValidate 通过表单访问控件,因此 name 该属性是必填项,缺少该属性则不会显示消息。原始版本还加载了两个不同的 AngularJS 版本,分别是 1.6.4 和 1.6.4。 Google CDN 与 1.6.9 版本一起,但从未链接 Bootstrap 即使这个例子取决于它的 form-group 和 form-control 用于定位错误文本的类。
💡注意: jcs-autoValidate 是一个社区项目,目前已停止维护。它仍然可以在现有的 AngularJS 应用程序中使用,但内置的自动验证功能已不再可用。 ngMessages 对于任何新事物,前面提到的方法都是更安全的选择。
Code 说明
- 包含了所有自动验证功能的“jcs-auto-validate.js”脚本。
- 每个控件及其周围的 div 元素都放置在“form-group”类中,模块会将消息注入到该类中。
- 控件同时包含一个id和一个
name和 Bootstrap 提供form-control样式。 - “jcs-autoValidate”模块被列为AngularJS模块的依赖项。
输出
默认情况下,表单将完全按照编写的内容呈现。
提交空白表单后,会显示“此字段为必填项”的消息,该消息完全由 jcs-autoValidate 生成。表单验证通过后,剩下的问题是用户在提交表单时会看到什么。
用户对 Ladda 按钮的反馈
“Ladda”按钮是一个构建在……之上的框架 JavaScript 按下按钮时,按钮会产生视觉效果。
如果按钮被赋予“ladda”属性并被按下,则会显示旋转效果。此外,还有不同的数据样式可用于实现其他视觉效果。
下面的示例展示了一个带有提交按钮的简单表单。按下按钮后,表单上会出现旋转效果。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Event Registration</title> <link rel="stylesheet" href="lib/bootstrap.css"> <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script> <script src="lib/angular-ladda.min.js"></script> </head> <body> <h1>Guru99 Event</h1> <div ng-app="DemoApp" ng-controller="DemoController"> <form name="myForm" novalidate ng-submit="submit()"> <button class="btn btn-primary" type="submit" ladda="submitting" name="sbutton" data-style="expand-right">Submit</button> </form> </div> <script> var app = angular.module('DemoApp', ['angular-ladda']); app.controller('DemoController', function($scope) { $scope.submitting = false; $scope.submit = function() { $scope.submitting = true; }; }); </script> </body> </html>
⚠️更正: 原始加载 angular-ladda.js 和 angular-ladda.min.js 同时,它注册了同一个模块两次,并且又引入了两个 AngularJS 版本。它还列出了 jcs-autoValidate 作为本示例中从未使用的依赖项。此处加载了每个库的一个副本。
Code 说明
- “”提交”指令调用名为“submit”的函数,该函数会更改按钮的ladda属性。
- ladda 属性属于 Ladda 框架,用于添加旋转效果。它的值绑定到……
submitting变量。 - data-style 属性是 Ladda 的另一个属性,用于选择不同的视觉效果。
- 要使框架正常工作,必须将“angular-ladda”模块添加到AngularJS应用程序中。
- 此
submitting变量初始化为 false,因此按钮启动时不会有旋转效果。 - 提交函数设置
submitting设置为 true 即可应用该效果。在实际应用中,一旦服务器响应,该值就会重置为 false,否则按钮会一直旋转。
输出
表单首次显示时,提交按钮会以最简洁的形式显示。
当按钮被按下时, submitting 变量被设置为 true。该值会传递给按钮的“ladda”属性,从而产生旋转效果。














