3

我正在尝试创建一个指令来检查输入到文本框中的值的唯一性。但是一旦 scope.$watch 被包装到 ctrl.$parsers.push() 函数中,newVal 和 oldVal 总是未定义。

有人知道为什么 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");
                    }
                });
4

2 回答 2

2

您不断获取未定义值的原因是因为您没有从解析器函数返回定义的值。

从 $parsers 的角度文档中:

每当控件从 DOM 读取值时,作为管道执行的函数数组。依次调用每个函数,将值传递给下一个函数。用于清理/转换值以及验证。对于验证,解析器应该使用 $setValidity() 更新有效性状态,并为无效值返回 undefined。

因为您的解析器中没有 return 语句,所以您总是返回 undefined(无效值)。

这是我认为您希望实施的工作的工作人员。

这是指令的代码:

.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.
            });
        }
    };
});
于 2013-09-21T21:53:29.870 回答
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

于 2013-09-21T21:51:33.457 回答