我正在尝试创建一个指令,用于检查输入到文本框中的值的唯一性。但是newVal和oldVal一直都是未定义的范围。$ watch包含在ctrl。$ parsers.push()函数中。
有人知道为什么newVal和oldVal未定义吗?
这是JSFiddle:
http://jsfiddle.net/charms/v6ttW/7/
HTML
<div ng-app="myApp" ng-controller="TestCtrl">
{{testVar}}
<form novalidate>
<input type="text" name="user.email" ng-model="user.email" email-used="/api/user"/>
</form>
</div>
Angularjs
angular.module('myApp', [])
.controller('TestCtrl', ['$scope',function($scope) {
$scope.user = {email: 'abc', name: 'myname'};
$scope.testVar = "Test";
}])
.directive('emailUsed', [function() {
return {
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
console.log("executing");
ctrl.$parsers.push(function() {
ctrl.$setValidity('eaCheckingUniqueValue', true);
if(ctrl.$valid) {
console.log("valid");
scope.oldValues = [];
scope.$watch(attr.ngModel, function(newVal, oldVal) {
scope.oldValues.push(newVal);
console.log("new value is: " + newVal);
});
console.log("valid is true");
} else {
console.log("valid is false");
}
});
答案 0 :(得分:2)
继续获取未定义值的原因是因为您没有从解析器函数返回定义的值。
来自$ parsers的角度文档:
每当控件执行时作为管道执行的函数数组 从DOM读取值。反过来,每个函数都被调用 价值一直到下一个。用于清理/转换值为 以及验证。为了验证,解析器应该更新 有效状态使用$ setValidity(),并返回undefined为invalid 值。
因为解析器中没有return语句,所以总是返回undefined(无效值)。
以下是我认为您要实施的内容的working plunker。
以下是该指令的代码:
.directive('emailUsed', function () {
return {
require: 'ngModel',
link: function (scope, elem, attr, ctrl) {
scope.oldValues = [];
scope.$watch(attr.ngModel, function(newVal, oldVal) {
if (angular.isDefined(newVal)) {
scope.oldValues.push(newVal);
}
});
ctrl.$parsers.push(function () {
if (ctrl.$viewValue.indexOf('@') !== -1) {
ctrl.$setValidity('eaCheckingUniqueValue', true);
return ctrl.$viewValue;
}
ctrl.$setValidity('eaCheckingUniqueValue', false);
return undefined; // Model is not valid so return undefined.
});
}
};
});
答案 1 :(得分:1)
要回答你的问题“每当值发生变化时我将如何将ngModel的值输入到我的指令中?”,每个解析器函数都会将新值作为参数接收:
link: function(scope, elem, attr, ctrl) {
console.log("executing");
scope.oldValues = [];
ctrl.$parsers.push(function(newVal) {
ctrl.$setValidity('eaCheckingUniqueValue', true);
if(ctrl.$valid) {
console.log("valid");
scope.oldValues.push(newVal);
console.log("new value is: " + newVal);
} else {
console.log("valid is false");
}
... // see mortalapeman's answer for a complete parser implementation
});
}