范围内的newValue。$ watch未定义

时间:2013-09-21 18:38:17

标签: javascript angularjs

我正在尝试创建一个指令,用于检查输入到文本框中的值的唯一性。但是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");
                    }
                });

2 个答案:

答案 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
   });
}

fiddle