我在'email'输入字段中使用'required'和'email'验证器。验证器使用解析器和格式化程序,它们工作正常。但是,我也对'bind'事件进行了一些验证。
这是指令:
angular.module('simpleRepairApp')
.directive('uniqueEmail', function (Checker) {
return {
require:'ngModel',
restrict:'A',
link:function ($scope, element, attrs, model) {
var last = '';
var current = '';
element.bind('blur', function() {
current = element.val();
console.log(current, last);
if(current !== last){
Checker.email({ email:current }).then(
function(response) {
model.$setValidity('uniqueEmail', response.available);
}
);
}
last = current;
});
}
};
});
我需要在用户点击字段后检查电子邮件是否已存在于数据库中(我不想检查每次按键或更改)。
我遇到的问题是,在执行唯一验证后,它会显示唯一的错误消息,但在您键入以更正电子邮件后,模型值将保持未定义状态。您必须单击输入,然后再次定义模型中的值。
任何人都可以帮我解决这个问题,它让我疯狂!:)
工作解决方案:
angular.module('simpleRepairApp')
.directive('emailUnique', function () {
return {
restrict: 'E',
require: ['form', 'ngModel'],
scope: {
'form': '=form',
'model': '=ngModel',
'labelClass': '@',
'inputClass': '@'
},
compile: function(element, attrs)
{
if (!attrs.labelClass) { attrs.labelClass = 'col-sm-4'; }
if (!attrs.inputClass) { attrs.inputClass = 'col-sm-8'; }
attrs.required = attrs.required == 'true';
},
controller: function($scope, Checker) {
$scope.checkEmail = function() {
var email = $scope.form.email.$viewValue;
var checkField = $scope.form.emailCheck;
Checker.email({ email:email }).then(
function(response) {
checkField.$setValidity('unique', response.available);
$scope.form.$setValidity('check', true);
checkField.hasVisit = true;
}
);
};
$scope.setUnchecked = function() {
console.log($scope.form);
$scope.form.emailCheck.hasVisited = false;
$scope.form.$setValidity('check', false);
$scope.form.emailCheck.$setValidity('unique', true);
};
},
template: '<div ng-class="{ \'has-error\' : !form.email.$valid || !form.emailCheck.$valid }">' +
'<label class="{{ labelClass }} control-label required" for="email" translate>E-mail</label>' +
'<div class="{{ inputClass }}">' +
'<input name="email" class="form-control" type="email" id="email" ng-model="model" ng-change="setUnchecked()" ng-blur="checkEmail()" ng-required="true" autocomplete="off">' +
'<div class="help-block" ng-show="(!form.email.$valid || !form.emailCheck.$valid) && !form.email.$pristine">' +
'<div ng-messages="form.email.$error">' +
'<div ng-message="required"><span translate>Please enter your e-mail.</span></div>' +
'<div ng-message="email"><span translate>Please enter a valid e-mail.</span></div>' +
'</div> ' +
'<div ng-messages="form.emailCheck.$error">' +
'<div ng-message="check"><span translate>E-mail will be checked upon blur.</span></div>' +
'<div ng-message="unique"><span translate>This e-mail is already in use.</span></div>' +
'</div> ' +
'</div>' +
'<input name="emailCheck" type="hidden" class="form-control" ng-model="checked">' +
'<div class="help-block" ng-messages="form.emailCheck.$error" ng-show="!form.emailCheck.$valid">' +
'</div>' +
'</div>' +
'</div>'
};
});
答案 0 :(得分:2)
我认为通过制定指令可能会使事情变得复杂,为什么不简单地将控制器添加到控制器中?
注意:如果这些方法中的任何一种方法对您有用,我就不熟悉了,但是我将它们添加为不会绑定到&#34;模糊&#34;事件,而是在MODEL发生变化时触发事件。这是角度设计的目的。我还假设您的Checker正确处理承诺
第一种替代方法(使用$ watch)
<form name="myForm" ng-controller="ExampleController">
<input type="email" name="input" ng-model="text" required />
</form>
然后在您的ng-app控制器中:
function isNullOrUndefined(value) {
return (value == 'undefined' || value == null);
}
//listener on the ng-model='text', waiting for the data to get dirty
$scope.$watch('text', function (newValue, oldValue) {
if (newValue != oldValue)
{
var truthyVal = !(isNullOrUndefined(newValue));
if (truthyVal) {
//angular's way of checking validity as well
//$scope.myForm.text.$valid
Checker.email({ email:current }).then(
function(response) {
model.$setValidity('textErr', response.available);
}
}
}
}, true);
第二种替代方法(使用ng-change):
<form name="myForm" ng-controller="ExampleController">
<input type="email" name="input" ng-model="text" ng-change="checkEmail()" required />
</form>
$scope.checkEmail = function(){
Checker.email({ email:current }).then(
function(response) {
model.$setValidity('textErr', response.available);
}
}
答案 1 :(得分:0)
由于您对模糊事件具有约束力,因此验证无法按您的方式工作。在该功能可以运行之前,您必须单击该字段。如果您确实希望它在完成键入电子邮件时进行验证,那么您将必须绑定到某种键事件。
我的建议是绑定到keyup,只在电子邮件地址看起来有效时才进行服务器端检查。