更改指令Angularjs中的模型值

时间:2018-02-08 09:03:22

标签: angularjs angularjs-directive angularjs-ng-model

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

我已经创建了一个指令,但是在blur事件之后,渲染视图可以工作,但它不会改变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

2 个答案:

答案 0 :(得分:1)

指令代码运行在if语句之后并返回&#34; undefined&#34;(因为没有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;

      });
    }
  };
});

答案 1 :(得分:1)

如果您只需更改视图和模型值,则不需要$parsers(当然,这不是一个很好的做法,可以绑定到解析器内部的事件,因为它会触发每个事件 - 来自DOM的$viewValue更改的时间):

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>

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