Chr*_*ong 7 angularjs angularjs-directive
我正在尝试为电子邮件字段实现表单验证.验证应该做到以下:
我希望显示第一条消息,如果该字段为空,如果电子邮件无效并且出现第三条消息,则会显示第二条消息,如果找到电子邮件地址,因此一次不唯一.
如果我只尝试使用"required"属性,但是一旦我添加了我的email-available指令属性,它就不再检查电子邮件的格式,并且email-available指令与所需属性一起执行.两个消息都会弹出,但我只希望用户一次看到一条消息.
我正在使用angularjs 1.1.3.
谁能告诉我,我可能做错了什么?
HTML
<div id="user_mod" class="mod_form" ng-show="userModScreenIsVisible">
<form name="mod_user" novalidate>
<input type="email" name="email" ng-model="user.email" placeholder="E-Mail" required email-available/>
<div class="user-help" ng-show="mod_user.email.$dirty && mod_user.email.$invalid">Invalid:
<span ng-show="mod_user.email.$error.required">Please enter your email.</span>
<span ng-show="mod_user.email.$error.email">This is not a valid email.</span>
<span ng-show="mod_user.email.$error.emailAvailable">This email address is already taken.</span>
</div>
</form>
Run Code Online (Sandbox Code Playgroud)
指示
directive('emailAvailable', function($http) { // available
return {
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
ctrl.$setValidity('emailAvailable', false);
if(viewValue !== "" && typeof viewValue !== "undefined") {
console.log("variable is defined");
$http.get('/api/user/email/' + viewValue + '/available')
.success(function(data, status, headers, config) {
console.log(status);
ctrl.$setValidity('emailAvailable', true);
return viewValue;
})
.error(function(data, status, headers, config) {
console.log("error");
ctrl.$setValidity('emailAvailable', false);
return undefined;
});
} else {
console.log("variable is undefined");
ctrl.setValidity('emailAvailable', false);
return undefined;
}
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
Ben*_*esh 19
我看到你已经解决了自己的问题,但我想我可以在这里给你一些提示/建议(我希望):
1)你需要做的一切,以确保您的验证已运行后,内置的角度验证了push()它在ctrl.$parsers,而不是unshift()它.
2)由于先前运行的验证程序显示它无效(即如果字段已经无效,如果您不想进行Ajax调用),则要使验证程序无法运行.您只需要ctrl.$invalid在if验证器内部签入一份声明.
3)您需要$setValidity()在开始ajax呼叫之前单独呼叫以及接收之后使表单无效.这样,在AJAX返回之前,您的表单无效,并说明它是否有效.
4)这可能很小,但除非你添加一个,否则ctrl.$formatter最初分配给$ scope中对象的值在写入屏幕之前不会被验证.如果您的表单通过路由,ng-repeat或ng-include动态添加到屏幕,并且预先填充了数据,则可能会出现问题.通常所有验证器都应该有一个$ parser组件(view - > model)和一个$ formatter组件(model - > view).
5)谨慎一点.如果模型无效,大多数验证器都将完全删除模型中的值.因为你正在进行异步调用,所以你必须立即在你的解析器函数中返回viewValue.通常,undefined如果字段无效,则解析器函数将返回,这可以防止无效数据出现在模型中.
6)由于验证器具有在$ error对象中维护的状态,因此在最初命中此异步验证器时,您需要清除它.见下文.
7)旁注:在你的回答中,我注意到你在ajax响应处理程序中返回值...这对你没有任何作用.因为调用是异步的,所以你总是从该解析器返回undefined.它会更新你的型号吗?如果确实如此,我会感到惊讶.
以下是我如何修改您的原始指令以使其按您可能的方式工作:
app.directive('emailAvailable', function($http, $timeout) { // available
return {
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
console.log(ctrl);
// push the validator on so it runs last.
ctrl.$parsers.push(function(viewValue) {
// set it to true here, otherwise it will not
// clear out when previous validators fail.
ctrl.$setValidity('emailAvailable', true);
if(ctrl.$valid) {
// set it to false here, because if we need to check
// the validity of the email, it's invalid until the
// AJAX responds.
ctrl.$setValidity('checkingEmail', false);
// now do your thing, chicken wing.
if(viewValue !== "" && typeof viewValue !== "undefined") {
$http.get('/api/user/email/' + viewValue + '/available')
.success(function(data, status, headers, config) {
ctrl.$setValidity('emailAvailable', true);
ctrl.$setValidity('checkingEmail', true);
})
.error(function(data, status, headers, config) {
ctrl.$setValidity('emailAvailable', false);
ctrl.$setValidity('checkingEmail', true);
});
} else {
ctrl.$setValidity('emailAvailable', false);
ctrl.$setValidity('checkingEmail', true);
}
}
return viewValue;
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6642 次 |
| 最近记录: |