我有一个有角度的应用程序验证注册表单。提交时,服务器也验证数据。我正在使用ng-messages以角度输出错误消息。
这是我的表单的缩短版本,到目前为止完美无缺。
<form name="signUpForm" novalidate data-ng-submit="attemptSignUp()">
<label for="firstName">First name</label>
<input type="email" name="email" id="email" required data-ng-model="data.user.email" />
<div class="error" data-ng-messages="signUpForm.email.$error" data-ng-show="signUpForm.$submitted" data-ng-cloak>
<p data-ng-message="required">Please provide your email</p>
</div>
</form>
服务器验证电子邮件地址是唯一的,如果没有,则返回422错误(来自Laravel 5),错误数组。
[
'email' => 'This email is already in use'
]
我想将此服务以及从服务器发回的任何其他消息合并到相关的ng-messages
块中。知道如何才能完成它吗?
答案 0 :(得分:27)
一个简单的解决方案是拥有两个数组。一个用于客户端,另一个用于服务器端错误,这些错误填充在控制器中。如果存在客户端错误,则可以隐藏服务器端错误,或者避免双重消息。
我选择使用两个数组而不是填充表单数组的原因是JavaScript控制器不应该知道或依赖于HTML的结构。 HTML AngularJS模板应绑定到控制器,而不是对等。
<form name="signUpForm" novalidate data-ng-submit="attemptSignUp()">
<label for="email">E-mail
<input type="email" name="email" id="email" required data-ng-model="data.user.email" />
<div class="error" data-ng-messages="signUpForm.email.$error" data-ng-show="signUpForm.$submitted" data-ng-cloak>
<p data-ng-message="required">Please provide your email</p>
</div>
<div class="error" data-ng-messages="serverErrors" data-ng-show="signUpForm.$submitted" data-ng-cloak>
<p data-ng-message="emailexists">Email already exists</p>
</div>
</label
</form>
标签上的注释:使用屏幕阅读器的用户如果没有包装在标签内,就不会大声朗读你的错误信息。
答案 1 :(得分:8)
嗯,这不是最优雅的解决方案,因为你真的应该 利用角度1.3.x中的asyncValidators然后创建你的 自定义验证指令。
资源
{p {3}}在帖子中找到了{p> http://plnkr.co/edit/s4jJAOqehBkFUC9osMsy?p=preview。可能在guy
但要小心,因为这绝不是一个准备好使用的完整示例。它主要用于演示目的,并让您知道从哪里开始。我没有打算清除以前的任何错误,重新验证表单或考虑其他验证错误。
想象一下你的控制器看起来像这样
$scope.serverValidations = {};
$scope.attemptSignUp = function(){
Api.validateEmail($scope.email).then(angular.noop, function(data){
$scope.serverValidations = data
for(prop in $scope.serverValidations){
if($scope.signUpForm[prop]){
angular.forEach($scope.serverValidations[prop],function(validation){
$scope.signUpForm[prop].$setValidity(validation.type, false);
});
}
}
});
}
并且包含验证错误的响应数据如下所示
{
email:[
{type:'unique', message:'This email is already in use'}
],
name:[
{type:'maxlength', message:'Your name is to long, get a new one :)'}
]
};
然后在您的HTML中,您可以这样做
<div class="error" data-ng-messages="signUpForm.name.$error" data-ng-cloak="">
<p data-ng-message="required">You don't have a name?</p>
<p ng-repeat="validation in serverValidations['name']" ng-message="{{validation.type}}">{{validation.message}}</p>
</div>
这是一个肮脏的Codepen:docs 当您按下提交时,在2秒后(命中虚假服务器所需的时间),将显示您的服务器验证。
答案 2 :(得分:7)
首先,您应该设置validity
和error messages
$scope.formErrors = {};
angular.forEach(errors, function(data, name) {
if (!vm.register_form[name]) {
return;
}
$scope.formErrors[name] = data.message;
//this will set errors->server to invalid state
$scope.register_form[name].$setValidity('server', false);
});
下一步将由ng-messages
<div ng-messages="register_form.email.$error">
<div ng-message="required">Email is required</div>
<div ng-message="email">Invalid email</div>
<div ng-message="server">{{formErrors.email}}</div>
</div>
答案 3 :(得分:-5)
我有一个类似的问题,但解决方案对我不起作用。我做了什么,它是/是一个黑客/解决方法,是发送不同的错误代码,并设置一个案例陈述。