Javascript 角度:对表单元素的指令访问
我有一个包含输入的表单标签:Javascript 角度:对表单元素的指令访问,javascript,angularjs,Javascript,Angularjs,我有一个包含输入的表单标签: <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" plac
<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>
我只想在输入端查看模型,并在模型更新时发出请求。
由于指令是在标签元素上定义的,因此未正确绑定ngModel。我做错了什么?我的watch表达式没有记录任何内容,因为它从不触发
我知道我可以手动抓取输入,但这似乎打破了我感到如此束缚的角度模式。令人沮丧的是,似乎有太多的方法以角度来做每件事,我永远无法判断我是否正确地处理了一个问题
-编辑-
为了提供我个人出于对更好方法的无知而采取的解决方案,我将采取以下措施:
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);
});
}
}
}]);
这是可行的,但我觉得它打破了角度规则。自定义验证是这样编写的:
'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的内置验证集合中 这里您需要的是ng模型。下面是这样一个指令的简单实现
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>
这将是正确的解决方案,因为它是通过angular ng model validation实现的,该验证也考虑了模型的有效性。但我需要将指令放在外部标签元素上。其他标记需要指令范围,因为像validationMessage这样的东西,以及其他将来添加的东西都需要在指令范围内。您能否坚持提供的标记,并以这种方式提供解决方案?此外,命名是confusign-该指令的目的不是验证输入,而是验证电子邮件是否存在于远程数据源。这引发了另一个问题,我是否需要制定两个指令来实现这一点?这是Angular让我恶心的案例之一。我觉得你应该能够用一段代码来完成这项工作。嗯,好的,我明白你的意思了。是的,我知道这种感觉。指令真是一团糟!在输入中使用ng模型,在指令中用{{formData.email}将其作为表达式计算,然后使用我的自定义验证器,怎么样???只是一种预感…哈哈,是的,似乎这就是一个人必须要做的,对吗?叹气我发誓总有一天我会掌握这个窍门的。无论哪种方式,我都会在弄清楚该怎么做后更新。谢谢你的帮助。你为什么在标签上用它?标签和它的内容是否封装在另一个指令中?是的,它们封装在另一个指令中,但这并不重要,一个人应该能够在没有包装指令的情况下使用它。重要的是emailValidationMessage应该能够根据指令范围进行响应。这是一个误导性的名称,因为这不是为了验证,而是为了检查电子邮件是否存在。您如何使用编辑块中提供的实现来验证电子邮件是否存在?我还不够深入;我要说的是,在这一点上,实际存在性检查是不相关的,因为我还没有到达我能够启动检查的地方!
<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>