如果两个输入字段具有相同的指令,则未定义scope。$ eval()

时间:2018-11-15 12:12:52

标签: angularjs angularjs-directive angularjs-validation

我正在尝试验证两个密码输入字段。只需确认它们相等即可。 (如果我的方法有误,则建议另一种方法

我已经实现了带有简单验证的指令,该指令可以检查“确认”密码是否与原始密码相同。但是该指令还会检查其他内容,因此我需要同时拥有两个输入字段。

问题是,当我在两个输入字段上都有指令时,无法通过属性读取它们的模型值(以检查它们是否匹配)。

这是一个正常工作的演示,没有第一个密码上的指令:

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {

});
app.directive('myDir', function() {
  return {
    require: 'ngModel',
    link: function(scope, elem, attrs, ctrl) {
      ctrl.$validators.mismatch = function(modelValue, viewValue) {
        // MAIN CODE:
        return viewValue === scope.$eval(attrs.confirm);
      };

      ctrl.$validators.short = function(modelValue, viewValue) {
        if (ctrl.$isEmpty(modelValue)) {
          return true;
        }
        if (modelValue.length >= 3) {
          return true;
        }
        return false;
      }
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">

  <form name="form1">
    <input type="password" name="password1" ng-model="pass1"><br>
    <input type="password" my-dir confirm="pass1" name="password2" ng-model="pass2"><br>
    <pre>{{form1.password2.$error | json}}</pre>
    <p ng-show="form1.password2.$error.mismatch" style="color:red">Passwords are different</p>
  </form>

</div>

如果我将第一个文件更改为:

<input type="password" my-dir confirm="pass2" name="password1" ng-model="pass1">

要在两个方向上进行验证,则两个字段的scope.$eval(attrs.confirm)都变为undefined

这是我的问题的演示:

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {

});
app.directive('myDir', function() {
  return {
    require: 'ngModel',
    link: function(scope, elem, attrs, ctrl) {
      ctrl.$validators.mismatch = function(modelValue, viewValue) {
        // `scope.$eval(attrs.confirm)` always undefined
        return viewValue === scope.$eval(attrs.confirm);
      };

      ctrl.$validators.short = function(modelValue, viewValue) {
        if (ctrl.$isEmpty(modelValue)) {
          return true;
        }
        if (modelValue.length >= 3) {
          return true;
        }
        return false;
      }
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">

  <form name="form1">
    <input type="password" my-dir confirm="pass2" name="password1" ng-model="pass1"><br>
    <input type="password" my-dir confirm="pass1" name="password2" ng-model="pass2"><br>
    <pre>{{form1.password2.$error | json}}</pre>
    <p ng-show="form1.password2.$error.mismatch || form1.password.$error.mismatch" style="color:red">
      Passwords are different
    </p>
  </form>

</div>

1 个答案:

答案 0 :(得分:0)

您需要做两件事: 1.添加ng-model-options="{allowInvalid: true}",以便无效值仍将更新作用域值。 2.现在您遇到了例如更改第二输入将不会触发第一重新验证。这是通过观察来完成的:

  <body ng-controller="MainCtrl" ng-init="x = 0; y = 0">
    <form name="form1">
    <input type="password" my-dir="{{y}}" confirm="pass2" name="password1" ng-model="pass1" ng-model-options="{allowInvalid: true}"
       ng-change="x = x + 1"><br>
    <input type="password" my-dir="{{x}}" confirm="pass1" name="password2" ng-model="pass2" ng-model-options="{allowInvalid: true}"
       ng-change="y = y + 1"><br>

attrs.$observe('myDir', function() {
    ctrl.$validate();
});

http://plnkr.co/edit/ws4tVWGXfFNR2yqLRJN7?p=preview

P.S。对于通常的字段,我会写my-dir =“ {{pass1}}”“,然后不需要$ eval和ng-change,但是需要密码...不确定