Angularjs setValidity 导致modelValue 不更新

标签 angularjs validation angularjs-directive

我在使用表单时遇到了一些基本问题。这就是我所做的。

我从这里获取了这个看起来很酷的指令:https://github.com/TheSharpieOne/angular-input-match

它看起来像这样:

directive('match', function () {
    return {
      require: 'ngModel',
      restrict: 'A',
      scope: {
        match: '='
      },
      link: function(scope, elem, attrs, ngModel) {
        scope.$watch(function() {
          return (ngModel.$pristine && angular.isUndefined(ngModel.$modelValue)) || scope.match === ngModel.$viewValue;
        }, function(currentValue, previousValue) {
          ngModel.$setValidity('match', currentValue);
        });
      }
    };
  });

本质上,该指令监视它附加到的元素的模型值,并将其与 match 属性中的模型值进行比较。

所以......例如,下面我们正在观察两个密码是否匹配:
Password: <input ng-model="password" type="password" />
Confirm: <input ng-model="passwordConfirm" type="password" match="password" />

该指令似乎有效,因为它适本地设置了 ng-valid-match 和 ng-invalid-match。

但是,一旦将其设置为无效,则 passwordConfirm 模型将永远不会再次更新。我已经完成了大量的 console.loggin,查看指令中的 ngModel,这是两个密码匹配时的样子:
Constructor {$viewValue: "asdf", $modelValue: undefined, $validators: Object, $parsers: Array[0], $formatters: Array[0]…}
$$debounceViewValueCommit: function (trigger, revalidate) {
$$invalidModelValue: "asdf"
$$lastCommittedViewValue: "asdf"
$$runValidators: function (modelValue, viewValue) {
$$validityState: ValidityState
$$writeModelToScope: function () {
$commitViewValue: function (revalidate) {
$dirty: true
$error: Object
$formatters: Array[0]
$invalid: false
$isEmpty: function (value) {
$modelValue: undefined
$name: "passwordConfirmation"
$parsers: Array[0]
$pristine: false
$render: function () {
$rollbackViewValue: function () {
$setPristine: function () {
$setTouched: function () {
$setUntouched: function () {
$setValidity: function (validationErrorKey, isValid) {
$setViewValue: function (value, trigger, revalidate) {
$touched: true
$untouched: false
$valid: true
$validate: function () {
$validators: Object
$viewChangeListeners: Array[0]
$viewValue: "asdf"
__proto__: Object

请注意,$viewValue 是正确的,但 $modelValue 被列为 undefined 并且 $invalidModelValue 仍然有一个值。

这是 html 的样子,再次当两个密码匹配时:
<input type="password" class="form-control ng-isolate-scope ng-dirty ng-valid-required ng-valid ng-valid-match ng-touched" id="passwordConfirmation" name="passwordConfirmation" placeholder="Confirm your password" ng-model="passwordConfirmation" required="" match="password" style="">

我在某处遗漏了什么吗?我已经绕圈跑了好几个小时了。

最佳答案

recent update ,更改了 $modelValue 的方式根据字段的有效性填充。如果该字段无效,则 $modelValue将设置为 undefined和一个新属性,$$invalidModelValue将填充该值。

作为使用 1.2.* 和 1.3.* 的解决方案,我想出了这个:

 .directive('match', function () {
    return {
        require: 'ngModel',
        restrict: 'A',
        scope: {
            match: '='
        },
        link: function(scope, elem, attrs, ctrl) {
            scope.$watch(function() {
                modelValue = ctrl.$modelValue || ctrl.$$invalidModelValue;
                return (ctrl.$pristine && angular.isUndefined(modelValue)) || scope.match === modelValue;
            }, function(currentValue) {
                ctrl.$setValidity('match', currentValue);
            });
        }
    };
});

Plunkr

虽然此解决方案适用于两个版本,但 1.3.* 具有新的 $validators新版本推荐使用的管道。

关于Angularjs setValidity 导致modelValue 不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24692775/

相关文章:

twitter-bootstrap - 将 datetimepicker 连接到 angularjs

wpf - Validation.Error 不是调用处理程序

ruby-on-rails - Rails 数据库唯一性验证不起作用

javascript - Vue.js:只允许带一位小数的范围内的数字

javascript - 使用angularjs打印时的页码

angularjs - 通过 PayPal API 将应用程序购物车与 PayPal 集成

javascript - JavaScript 中的 Getter 和 Setter。 setter 是如何实现的?用于 Angular Controller ?

javascript - 当值为空时,AngularJS避免错误消息

javascript - 如何在 Angular 动态表单字段内添加动态表单字段?

javascript - 如何在 Angular 1.5 组件中选择元素?