I'm trying to create a directive that will check the uniqueness of the value entered in to the text box. But newVal and oldVal are always undefined as soon scope.$watch is wrapped in to the ctrl.$parsers.push() function.
Does anybody know why newVal and oldVal are undefined?
Here is the JSFiddle:
/
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");
}
});
I'm trying to create a directive that will check the uniqueness of the value entered in to the text box. But newVal and oldVal are always undefined as soon scope.$watch is wrapped in to the ctrl.$parsers.push() function.
Does anybody know why newVal and oldVal are undefined?
Here is the JSFiddle:
http://jsfiddle/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");
}
});
Share
Improve this question
asked Sep 21, 2013 at 18:38
Christopher ArmstrongChristopher Armstrong
3,5576 gold badges37 silver badges41 bronze badges
2
-
3
You shouldn't be putting a
scope.$watch()
function inside of a parser, as it will register a newscope.$watch()
every time the parser is executed (which is every time the input changes). – rtcherry Commented Sep 21, 2013 at 18:56 - Thanks for your input rtcherry. That helps much already. Do you have any remendation how I would get the value of ngModel in to my directive everytime the value changes so that I can verify if it already exists? – Christopher Armstrong Commented Sep 21, 2013 at 19:24
2 Answers
Reset to default 2The reason you keep getting values that are undefined is because you are not returning a defined value from your parser function.
From the angular documentation for $parsers:
Array of functions to execute, as a pipeline, whenever the control reads value from the DOM. Each function is called, in turn, passing the value through to the next. Used to sanitize / convert the value as well as validation. For validation, the parsers should update the validity state using $setValidity(), and return undefined for invalid values.
Because you had no return statement in your parser, you were always returning undefined (an invalid value).
Here is working plunker of what I think you were looking to implement.
Here is the code for the directive:
.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.
});
}
};
});
To answer your question "how I would get the value of ngModel in to my directive everytime the value changes?", each parser function receives the new value as an argument:
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 plete parser implementation
});
}
fiddle
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745251415a4618698.html
评论列表(0条)