Angular 远程表单不显示错误
Angular remote form not displaying error
我创建了一个 angular 表单来显示从服务器收到的输入验证错误。除了一个小问题外,我的解决方案工作正常。
如果我提交没有值的表单,在页面加载后,我会从我的服务器收到正确的响应,即 422,但不会显示验证错误。如果我随后开始在输入中键入一个值,则验证错误会闪烁并消失。
我几乎可以肯定它与我的指令有关,但我不确定如何修复它。这是我当前的指令代码:
var appServices = angular.module('webFrontendApp.directives', []);
appServices.directive('serverError', function(){
return {
restrict: 'A',
require: '?ngModel',
link: function(scope,element,attrs,ctrl){
element.on('change keyup', function(){
scope.$apply(function(){
ctrl.$setValidity('server', true);
});
});
}
};
});
我认为问题出在这段代码的 element.on('change keyup'.. 部分。这就是为什么当我开始输入时错误消息闪烁的原因。另外,当我将其更改为 'change' 而不是 'change keyup',错误消息在我开始输入时永久显示。
有没有人知道即使我在第一次提交之前没有在输入中键入任何值,我如何显示错误消息?
根据评论更新
这是我的表格:
<form ng-submit="create(memberData)" name="form" novalidate>
<div class = "row form-group" ng-class = "{ 'has-error' : form.email.$dirty && form.email.$invalid }">
<input type="text" ng-model="memberData.email" placeholder="janedoe@mail.com" name="email" class="col-xs-12 form-control" server-error>
<span class="errors" ng-show="form.email.$dirty && form.email.$invalid">
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
<span ng-show="form.email.$error.server">{{errors.email}}</span>
</span>
</div>
<div class="row">
<button type="submit" class="btn btn-danger col-xs-12">Join Private Beta</button>
</div>
</form>
我的控制器:
$scope.memberData = {};
$scope.create = function() {
var error, success;
$scope.errors = {};
success = function() {
$scope.memberData = {};
};
error = function(result) {
angular.forEach(result.data.errors, function(errors, field) {
$scope.form[field].$setValidity('server', false);
$scope.errors[field] = errors.join(', ');
});
};
BetaMember.save({ beta_member: { email: $scope.memberData.email || "" }}).$promise.then(success, error);
};
由于表单本身没有 $setValidity 方法,因为没有 ng-model,并且假设服务器错误不是指单个字段(在这种情况下 $setValidity 方法是首选 ),我认为最简单的解决方案可能是这个:
创建一个带有一些随机验证的表单(这个只需要至少用户名)和一个可以显示自定义服务器错误的 div。
<div ng-controller="AppCtrl">
<form novalidate name="createForm">
<div class="inputWrap">
<input ng-model="name" name="name" type="text" required placeholder="John Doe">
<span ng-if="createForm.name.$dirty && createForm.name.$invalid">
Some kind of error!
</span>
</div>
<div ng-if="serverError">
{{ serverError.message }}
</div>
<input
value="Join Private Beta"
ng-disabled="createForm.$invalid || serverError"
ng-click="create()"
type="button">
</form>
</div>
然后在您的控制器中,您可以添加处理 YourService 的 create 方法(应该 return 一个承诺)和如果响应失败,您可以创建一个简单的对象,其中包含自定义服务器错误消息,如果需要,该对象也可用于禁用表单按钮。
var AppCtrl = function($scope, YourService){
// Properties
// Shared Properties
// Methods
function initCtrl(){}
// Shared Methods
$scope.create = function(){
YourService.makeCall().then(function(response){
// Success!
// Reset the custom error
$scope.serverError = null;
}, function(error){
// Do your http call and then if there's an error
// create the serverError object with a message
$scope.serverError = {
message : 'Some error message'
};
})
};
// Events
// Init controller
initCtrl();
};
AppCtrl.$inject = [
'$scope',
'YourService'
];
app.controller('AppCtrl', AppCtrl);
我的意思是这里的代码段非常简单,我只是想举个例子。没什么复杂的,但您可以将其扩展到更多。
似乎有一个非常简单的解决方法。因为我有过滤器 form.email.$dirty 在我看来,如果用户在没有先点击表单的情况下点击提交,则不会显示错误。
删除 form.email.$dirty 后只有 form.email.$invalid,效果很好。我认为这对我来说已经足够了,因为此验证取决于服务器响应,并且不会在提交表单之前触发。错误对象也在我的控制器中被清除,确保页面在首次加载时不会加载错误。
我创建了一个 angular 表单来显示从服务器收到的输入验证错误。除了一个小问题外,我的解决方案工作正常。 如果我提交没有值的表单,在页面加载后,我会从我的服务器收到正确的响应,即 422,但不会显示验证错误。如果我随后开始在输入中键入一个值,则验证错误会闪烁并消失。
我几乎可以肯定它与我的指令有关,但我不确定如何修复它。这是我当前的指令代码:
var appServices = angular.module('webFrontendApp.directives', []);
appServices.directive('serverError', function(){
return {
restrict: 'A',
require: '?ngModel',
link: function(scope,element,attrs,ctrl){
element.on('change keyup', function(){
scope.$apply(function(){
ctrl.$setValidity('server', true);
});
});
}
};
});
我认为问题出在这段代码的 element.on('change keyup'.. 部分。这就是为什么当我开始输入时错误消息闪烁的原因。另外,当我将其更改为 'change' 而不是 'change keyup',错误消息在我开始输入时永久显示。
有没有人知道即使我在第一次提交之前没有在输入中键入任何值,我如何显示错误消息?
根据评论更新
这是我的表格:
<form ng-submit="create(memberData)" name="form" novalidate>
<div class = "row form-group" ng-class = "{ 'has-error' : form.email.$dirty && form.email.$invalid }">
<input type="text" ng-model="memberData.email" placeholder="janedoe@mail.com" name="email" class="col-xs-12 form-control" server-error>
<span class="errors" ng-show="form.email.$dirty && form.email.$invalid">
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
<span ng-show="form.email.$error.server">{{errors.email}}</span>
</span>
</div>
<div class="row">
<button type="submit" class="btn btn-danger col-xs-12">Join Private Beta</button>
</div>
</form>
我的控制器:
$scope.memberData = {};
$scope.create = function() {
var error, success;
$scope.errors = {};
success = function() {
$scope.memberData = {};
};
error = function(result) {
angular.forEach(result.data.errors, function(errors, field) {
$scope.form[field].$setValidity('server', false);
$scope.errors[field] = errors.join(', ');
});
};
BetaMember.save({ beta_member: { email: $scope.memberData.email || "" }}).$promise.then(success, error);
};
由于表单本身没有 $setValidity 方法,因为没有 ng-model,并且假设服务器错误不是指单个字段(在这种情况下 $setValidity 方法是首选 ),我认为最简单的解决方案可能是这个:
创建一个带有一些随机验证的表单(这个只需要至少用户名)和一个可以显示自定义服务器错误的 div。
<div ng-controller="AppCtrl">
<form novalidate name="createForm">
<div class="inputWrap">
<input ng-model="name" name="name" type="text" required placeholder="John Doe">
<span ng-if="createForm.name.$dirty && createForm.name.$invalid">
Some kind of error!
</span>
</div>
<div ng-if="serverError">
{{ serverError.message }}
</div>
<input
value="Join Private Beta"
ng-disabled="createForm.$invalid || serverError"
ng-click="create()"
type="button">
</form>
</div>
然后在您的控制器中,您可以添加处理 YourService 的 create 方法(应该 return 一个承诺)和如果响应失败,您可以创建一个简单的对象,其中包含自定义服务器错误消息,如果需要,该对象也可用于禁用表单按钮。
var AppCtrl = function($scope, YourService){
// Properties
// Shared Properties
// Methods
function initCtrl(){}
// Shared Methods
$scope.create = function(){
YourService.makeCall().then(function(response){
// Success!
// Reset the custom error
$scope.serverError = null;
}, function(error){
// Do your http call and then if there's an error
// create the serverError object with a message
$scope.serverError = {
message : 'Some error message'
};
})
};
// Events
// Init controller
initCtrl();
};
AppCtrl.$inject = [
'$scope',
'YourService'
];
app.controller('AppCtrl', AppCtrl);
我的意思是这里的代码段非常简单,我只是想举个例子。没什么复杂的,但您可以将其扩展到更多。
似乎有一个非常简单的解决方法。因为我有过滤器 form.email.$dirty 在我看来,如果用户在没有先点击表单的情况下点击提交,则不会显示错误。
删除 form.email.$dirty 后只有 form.email.$invalid,效果很好。我认为这对我来说已经足够了,因为此验证取决于服务器响应,并且不会在提交表单之前触发。错误对象也在我的控制器中被清除,确保页面在首次加载时不会加载错误。