javascript - newValue in scope.$watch is undefined - Stack Overflow

I'm trying to create a directive that will check the uniqueness of the value entered in to the tex

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 new scope.$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
Add a ment  | 

2 Answers 2

Reset to default 2

The 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

相关推荐

  • javascript - newValue in scope.$watch is undefined - Stack Overflow

    I'm trying to create a directive that will check the uniqueness of the value entered in to the tex

    3小时前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信