更改指令中的模型值 Angularjs

Changing model value in directive Angularjs

我正在尝试为输入元素创建一个指令。当输入一个数字时,我想通过添加像“12”->“0012”这样的零来更新模糊事件的输入值。我有一个参数传递给指令以指定结果编号的长度,例如,如果数字的长度为 6 并且用户输入 123,则结果为 000123

我创建了一个指令,但在模糊事件之后,渲染视图可以工作,但它不会更改 ng-model

app.directive('addZeros', function() {
  return {
    restrict: 'A',
    scope: {
      addZeros: '=addZeros'
    },
    require: '?ngModel',

    link: function(scope, element, attrs, modelCtrl) {
      var addZeroOK = false;
      modelCtrl.$parsers.push(function(inputValue) {
        var num = parseInt(inputValue, 10);
        num = '' + num;
        var clean = num.replace(/[^0-9]/g, '');
        if (inputValue.length <= scope.addZeros) {
          scope.addZeros = parseInt(scope.addZeros, 10);
          if (isNaN(clean) || isNaN(scope.addZeros)) {
            return inputValue;
          }

          element.bind('blur', function(event) {
            if (clean.length > 0) {
              addZeroOK = true;
              while (clean.length < scope.addZeros) {
                clean = '0' + clean;
              }
            }
            scope.$apply(function() {
              modelCtrl.$setViewValue(clean);
              modelCtrl.$render();
              return clean;

            })

          });
          if (addZeroOK == false) {
            modelCtrl.$setViewValue(clean);
            modelCtrl.$render();
            return clean;
          }
        } else {
          var str = inputValue.slice(0, -1);
          modelCtrl.$setViewValue(str);
          modelCtrl.$render();
          return str;
        }
      });
    }
  };
});

Plnker:http://plnkr.co/edit/1ON1DtKZ6qjmT1i2U5pz?p=preview

指令代码经过您的 if 语句和 returns "undefined"(因为没有 return 语句)。参见 Plunker

app.directive('addZeros', function() {
  return {
    restrict: 'A',
    scope: {
      addZeros: '=addZeros'
    },
    require: '?ngModel',

    link: function(scope, element, attrs, modelCtrl) {
      var addZeroOK = false;
      modelCtrl.$parsers.push(function(inputValue) {
        var num = parseInt(inputValue, 10);
        num = '' + num;
        var clean = num.replace(/[^0-9]/g, '');
        if (inputValue.length <= scope.addZeros) {
          scope.addZeros = parseInt(scope.addZeros, 10);
          if (isNaN(clean) || isNaN(scope.addZeros)) {
            return inputValue;
          }

          element.bind('blur', function(event) {
            if (clean.length > 0) {
              addZeroOK = true;
              while (clean.length < scope.addZeros) {
                clean = '0' + clean;
              }
            }
            scope.$apply(function() {
              modelCtrl.$setViewValue(clean);
              modelCtrl.$render();
              return clean;

            })

          });
          if (addZeroOK == false) {
            modelCtrl.$setViewValue(clean);
            modelCtrl.$render();
            return clean;
          }
        } else {
          var str = inputValue.slice(0, -1);
          modelCtrl.$setViewValue(str);
          modelCtrl.$render();
          return str;
        }

        return inputValue;

      });
    }
  };
});

如果您只需要更改视图和模型值,则不需要 $parsers then (and of course this is not a good practice to bind to events inside of the parser since it is firing every-time the $viewValue,因为 DOM 已更改):

angular.module('plunker', [])
    .controller('MainCtrl', function ($scope) {

    })
    .directive('addZeros', function () {
        return {
            restrict: 'A',
            scope: {
                addZeros: '=addZeros'
            },
            require: '?ngModel',

            link: function (scope, element, attrs, modelCtrl) {
                scope.addZeros = parseInt(scope.addZeros, 10);
                var dRegex = new RegExp(/[^0-9.]/g);

                element.on('blur', function (event) {
                    modelCtrl.$setViewValue(getValue(modelCtrl.$modelValue));
                    modelCtrl.$render();
                });

                element.on("keypress", function (event) {
                    // allow only digits to be entered, or backspace and delete keys to be pressed
                    var allow = (event.charCode >= 48 && event.charCode <= 57) ||
                        (event.keyCode === 8 || event.keyCode === 46);

                    if (!allow) {
                        event.preventDefault();
                    }

                });

                function getValue(inputValue) {
                    var num = String(parseInt(inputValue, 10));
                    var clean = num.replace(dRegex, '');

                    if (inputValue.length <= scope.addZeros) {
                        if (!clean || isNaN(scope.addZeros)) {
                            return inputValue;
                        }
                    }

                    if (clean.length > 0) {
                        while (clean.length < scope.addZeros) {
                            clean = '0' + clean;
                        }
                    }
                    return clean;
                }

            }
        };
    });
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
<body ng-app="plunker">

    <div ng-controller="MainCtrl">
        <p>Input below will accept only numbers and add leading zeros</p>
        <h4>value of test1 : {{test1}}</h4>
        <p><input type="tel" ng-model="test1" add-zeros="4" class="form-control"/></p>
        <h4>value of test2 : {{test2}}</h4>
        <p><input type="tel" ng-model="test2" add-zeros="6" class="form-control"/></p>
    </div>

</body>

更新:修改为限制输入非数字。