我有一个包含输入的表单标签:
<label data-live-email-check="http://www.example-service-uri.com/">
<span class="embedded-label">Email</span>
<input ng-model="formData.email"
type="email"
name="email"
placeholder="Email"
required/>
<span class="message" ng-show="emailValidationMessage">{{emailValidationMessage}}</span>
</label>
我想创建一个指令,该指令接受data-live-email-check属性提供的URL,并将电子邮件发送到该URL,验证它是否已存在。
angular.module("App").directive("liveEmailCheck", [function () {
return {
restrict: "A",
scope: {
ngModel: "="
},
link: function (scope, element, attrs) {
scope.$watch(
function(){
return scope.ngModel
},
function(newVal){
console.log(newVal);
}
);
}
}
}]);
我只想在输入上观看模型,并在更新时触发请求。 由于指令是在标签元素上定义的,因此ngModel未正确绑定。我究竟做错了什么?我的监视表达式没有记录任何内容,因为它永远不会触发。
我知道我可以手动抓住输入,但这看起来好像我打破了我感觉如此“束缚”的“角度模式”。令人沮丧的是,似乎有很多方法可以在Angular中完成所有工作,我无法判断我是否正确接近问题。
- 编辑 -
提供我个人将采取的解决方案(出于对“更好”方式的无知),将是以下内容:
angular.module("App").directive("liveEmailCheck", [function () {
return {
restrict: "A",
require: ["^form"],
link: function (scope, element, attrs, ctrl) {
var formCtrl = ctrl[0];
scope.formEl = formCtrl[element.find("input").attr("name")];
scope.$watch(function(){return scope.formEl.$valid},
function(newVal){
console.log(newVal);
});
}
}
}]);
这个工作,但我觉得它“打破了角度规则”。
答案 0 :(得分:0)
自定义验证的写法如下:
'use strict';
angular.module('App')
.directive('liveEmailCheck', function (){
return {
require: 'ngModel',
link: function (scope, elem, attr, ngModel){
ngModel.$validators.liveEmailCheck= function (value){
//Your logic here or in a factory
};
}
};
});
然后在你的HTML上就像
<input type="email" live-email-check="liveEmailCheck>
基本上,您将自己的验证添加到angular的内置验证集中。
答案 1 :(得分:0)
这里需要的是ng-model asyncValidator。这是一个这样的指令的简单实现。
angular.module("App").directive('asyncEmailValidator', function ($http) {
return {
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
var emailValidationUrl = attrs.asyncEmailValidator;
ngModel.$asyncValidators.emailValidator = function (modelValue, viewValue) {
var value = modelValue || viewValue;
// NOTE: don't forget to correctly add the value to the url
return $http(emailValidationUrl + value).then(function (validationResponse) {
// NOTE: return rejected promise if validation failed else true
});
};
}
};
});
如何在您的案例中使用它:
<label>
<span class="embedded-label">Email</span>
<input ng-model="formData.email"
async-email-validator="http://www.example-service-uri.com/"
type="email"
name="email"
placeholder="Email"
required/>
<span class="message" ng-show="<FormNameHere>.email.$error.emailValidator">
{{emailValidationMessage}}
</span>
</label>
这将是正确的解决方案,因为它是通过角度ng模型验证实现的,该验证也考虑了模型的有效性。