30

有没有办法在自定义表单验证中传递错误消息?

例如,我有一个检查用户名的指令。有三种可能的结果:

  1. 它是有效的
  2. 它是无效的,因为它不是一个好的用户名(“this.is-invalid”)
  3. 它是无效的,因为它已经在使用中

我有一个类似(简化伪html)的指令:

<input type="text" namecheck></input><span ng-show="name.$error.namecheck">You had an error {{ error }}</span>

在我的自定义指令中,我可以做到

// check for a conflict and valid name here
ngModel.$setValidity("namecheck",false);

但是如何传递一条错误消息来指示问题是冲突还是无效名称?有什么类似的ngModel.$setValidityErrorMessage()吗?

4

3 回答 3

51

正如我在评论中所写,我只是想通了。我只需要使用不同的有效性标志。没有什么说我必须使用与$setValidity()指令名称相同的键!

<span ng-show="name.$error.nameinvalid">This is not a valid username, it must be alphanmueric</span>
<span ng-show="name.$error.nametaken">Sorry, the username {{ name }} is already taken</span>

在指令中

// if I got a 409
ngModel.$setValidity("nametaken",false);
// if I got a 400
ngModel.$setValidity("nameinvalid",false);

的名称$error 错误信息!

于 2013-10-22T15:52:57.990 回答
2

不会。在表单元素上设置有效性只是简单地将适当的类添加到元素中,然后可以使用它来设置元素的样式以指示错误。没有任何错误消息表明元素无效的原因。Angular 不提供这种支持。

required您可能已经注意到在空字段上弹出的错误消息?在 chrome 中,他们会说:“请填写此字段”或其他内容。这些是特定于浏览器的,与角度无关。

您必须推出自己的错误消息服务。您可以使用相同的ng-invalid类来检查表单元素何时无效并据此显示错误消息,但 Angular 并没有提供开箱即用的功能。

angular docs 中有一个示例(在此处找到),它显示了您可以做到这一点的一种方法。

更新:

从 Angular 1.3 开始,现在支持ngMessageandngMessages指令。这些新指令试图减少表单验证和错误消息传递的麻烦。这些指令的角度文档在这里。查看链接以获取更多详细信息。

于 2013-10-22T15:04:39.440 回答
2

在我看来,您的三个规则包括客户端和服务器验证。我将在客户端验证前两个,在服务器端验证最后一条规则。因为用户名是否重复,我们会在将其发布到服务器之前获取它。所以,我的做法如下:

 <div class="col-md-offset-3 col-md-9" ng-show="detailForm.$error && detailForm.name.$invalid && (detailForm.name.$touched || detailForm.$submitted)"
                     ng-messages="detailForm.name.$error">
          <div class="error-message" ng-message="required">the field is required </div>
          <div class="error-message" ng-message="maxlength">you are too lang</div>
          <div class="error-message" ng-message="pattern">your format is incorrect </div>
 </div>
 <div class="col-md-offset-3 col-md-9" ng-show="serverError && serverError.name">
          <div class="error-message">{{serverError.name}}</div>
 </div>
于 2018-03-14T08:05:02.903 回答