当我想检查邮件是否已在数据库中注册时,我遇到了问题,但仅在模糊事件上(我不希望它检查每次更改)。所以我写了一个指令,我可以在我的应用程序的其他地方重复使用。但问题是即使我仍然没有模糊,指令仍在检查,这是我的plnkr供参考:http://plnkr.co/edit/eUPFxIc78Wkl4mCX6hrk?p=preview
这是我的指令代码:
app.directive('checkEmail', function(userService){
return{
restrict: "A",
require:'ngModel',
link: function( scope, ele, attrs, ctrl ){
ele.bind('blur', function(){
console.log("Run in blur!");
ctrl.$parsers.unshift(function( email ){
console.log("Email is ", email);
// Checking to see if the email has been already registered
if( ele.val() && userService.isDuplicateEmail(email) ){
ctrl.$setValidity('isDuplicatedEmail', true );
}else{
ctrl.$setValidity('isDuplicatedEmail', false );
}
});
})
}
}
})
抱歉,我是棱角分明的新手,这个简单的任务已经让我疯狂了。请看看我的指令并告诉我如何解决这个问题。提前致谢
答案 0 :(得分:3)
请参阅此处了解工作样本http://plnkr.co/edit/lT9kO4nU0OeBG3g8lULG?p=preview
请不要忘记添加范围。$ apply以更新您的用户界面
app.directive('checkEmail', function(userService) {
return {
restrict: "A",
require: 'ngModel',
link: function(scope, ele, attrs, ctrl) {
ele.bind('blur', function() {
scope.$apply(function() {
console.log("Run in blur!");
// Checking to see if the email has been already registered
if (userService.isDuplicateEmail(scope.email)) {
ctrl.$setValidity('isDuplicatedEmail', false);
return scope.email;;
} else {
ctrl.$setValidity('isDuplicatedEmail', true);
return scope.email;
}
});
})
}
}
})
答案 1 :(得分:1)
如果你只需要在模糊时检查电子邮件,那么你不需要在ng-model
的{{1}}数组中传递它。只需在模糊时更改有效性。
<强> DEMO 强>
这样的事情:
$parser
或者,如果您从服务器异步检查电子邮件,那么这可能不利于您。以下示例是一个更好的答案:
<强> DEMO 强>
以下服务,要求提供来自服务器的电子邮件列表,并解决电子邮件是否存在(真实)或不存在(错误)的承诺。
ele.bind('blur', function(){
ctrl.$setValidity('isDuplicatedEmail', ctrl.$viewValue && userService.isDuplicateEmail(ctrl.$modelValue));
scope.$digest();
});
下面的指令将app.service('userServiceAsync', function($http, $q) {
this.isDuplicateEmailAsync = function(email) {
var deferred = $q.defer(), i;
$http.get('users.json')
.success(function(users) {
for(i = 0; i < users.length; i++) {
if(users[i].email == email) {
deferred.resolve(true);
return;
}
}
deferred.resolve(false);
})
.error(function() {
deferred.resolve(false);
});
return deferred.promise;
};
});
有效性键设置为true或false,具体取决于isDuplicatedEmail
方法的已解析值。作为奖励,我在userServiceAsync.isDuplicateEmailAsync ()
对象中添加了一个决定性键,以检查异步请求是否仍在进行(使用ngModelController
键)。
__CHECKING_EMAIL
<强> HTML 强>
app.directive('checkEmailAsync', function(userServiceAsync) {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
elem.bind('blur', function() {
ctrl.__CHECKING_EMAIL = true;
userServiceAsync.isDuplicateEmailAsync(ctrl.$viewValue).then(function(hasEmail) {
ctrl.$setValidity('isDuplicatedEmail', !hasEmail);
})['finally'](function() {
ctrl.__CHECKING_EMAIL = false;
});
});
}
}
});
答案 2 :(得分:1)
$ parser.unshift在模型更改时执行,但您确实想要&#34;模糊&#34;,...要么检查ngModelOptions&#39; &#34; updateOn&#34;或删除不合时宜的......
你也可以使用ctrl。$ viewValue。
ele.bind('blur', function(){
console.log("Run in blur!");
//ctrl.$parsers.unshift(function( email ){
email = ctrl.$viewValue;
console.log("Email is ", email);
// Checking to see if the email has been already registered
if( !!email && userService.isDuplicateEmail(email) ){
ctrl.$setValidity('isDuplicatedEmail', true );
return email;;
}else{
ctrl.$setValidity('isDuplicatedEmail', false );
return email;
}
//});
})
答案 3 :(得分:1)
@ryeballar,对不起,但这对我来说仍然不合适。我修改了你的plnk,以便它只适用于异步。所以我的困惑就是这条线
ctrl.$setValidity('isDuplicatedEmail', !hasEmail);
,您可以访问新的here
如果我之前没有输入“!”,那么布尔值似乎不正确,您可以在控制台日志中查看它并查看其值,就像电子邮件不重复时一样,服务返回false,然后我们将有效性设置为"TRUE"
,以使其看起来"RIGHT"
。
这是指令:
elem.bind('blur', function() {
ctrl.__CHECKING_EMAIL = true;
userServiceAsync.isDuplicateEmailAsync(ctrl.$viewValue).then(function(hasEmail) {
console.log("hasEmail: ", hasEmail);
console.log("!hasEmail: ", !hasEmail);
scope.hasEmail = hasEmail;
// HERE IS THE CONFUSION, WHY !hasEmail works correctly ????
// THIS WILL GIVE THE WRONG ANSWER
// ctrl.$setValidity('isDuplicatedEmail', hasEmail);
// THIS WILL GIVE THE RIGHT ANSWER
ctrl.$setValidity('isDuplicatedEmail', !hasEmail);
})['finally'](function() {
ctrl.__CHECKING_EMAIL = false;
});
});