Angularjs setValidity causing modelValue to not update

前端 未结 3 1649
既然无缘
既然无缘 2021-01-03 01:00

I\'m having some basic trouble with a form. Here\'s what I did.

I snagged this cool looking directive from here: https://github.com/TheSharpieOne/angular-input-matc

相关标签:
3条回答
  • 2021-01-03 01:08

    Might be related to the fact that you are using

    scope: { 
         match : "=" 
    }
    

    That create an isolated scope for your directive and doesn't herite from the parent scope where your ngModel is.

    I suggest trying to remove that scope part of your directive and access it from attributes instead.

    It will become something like :

    directive('match', function () {
        return {
          require: 'ngModel',
          restrict: 'A',
          link: function(scope, elem, attrs, ngModel) {
            scope.match = attrs.match;
            scope.$watch(function() {
              return (ngModel.$pristine && angular.isUndefined(ngModel.$modelValue)) || scope.match === ngModel.$viewValue;
            }, function(currentValue, previousValue) {
              ngModel.$setValidity('match', currentValue);
            });
          }
        };
      });
    
    0 讨论(0)
  • 2021-01-03 01:15

    It looks like maybe using $setValidity is not the way to go here. I found this question that proposes a different solution, using $validators and $validate(), and this is working for me great. The new code looks like this:

    directive('match', function () {
      return {
        require: 'ngModel',
        restrict: 'A',
        scope: {
          match: '='
        },
        link: function(scope, elem, attrs, ngModel) {
          scope.$watch('match', function(pass){
            ngModel.$validate();
          });
          ngModel.$validators.match = function(modelValue, viewValue){
            var value = modelValue || viewValue;
            var match = scope.match;
            return value === match;
          };
        }
      };
    });
    
    0 讨论(0)
  • 2021-01-03 01:17

    In a recent update, a change was made to the way the $modelValue is populated based on the validity of the field. If the field is invalid, the $modelValue will be set to undefined and a new attribute, $$invalidModelValue will be populated with the value.

    As a solution to work with 1.2.* and 1.3.* I have come up with this:

     .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

    While this solution works with both version, 1.3.* has the new $validators pipeline which is recommended for the new version.

    0 讨论(0)
提交回复
热议问题