【问题标题】:Changing model value in directive Angularjs在指令 Angularjs 中更改模型值
【发布时间】:2018-07-18 18:51:40
【问题描述】:

我正在尝试为输入元素创建指令。当输入一个数字时,我想通过添加像“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

【问题讨论】:

  • 请检查此链接,看起来问题是当您输入 type="number" 时,尝试将其更改为带有模式的文本。希望这会告诉您方法)link跨度>
  • 看起来这个人也有同样的问题,请检查,他的解决方案link
  • 谢谢@Beny,但我的问题是在我的 ng-model 中获取值,添加零工作并且在输入中我有正确的值,但 ng- modal 为空,您可以查看链接plnkr.co/edit/1ON1DtKZ6qjmT1i2U5pz?p=preview 了解更多详情
  • 正确,我错过了。

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


【解决方案1】:

如果您只需要更改视图和模型值,则不需要$parsers(当然这不是绑定到解析器内部事件的好习惯,因为它每次都会触发$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>

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

【讨论】:

  • 谢谢@Stanislav Kvitash 的建议,但我希望这个指令只接受数字
  • @AmineAlaoui 它接受数字,不是吗?或者你的意思是你想限制输入非数字?接受的答案要么不会阻止在输入中输入任何内容,而且正如我所说 - 在 $parser 函数中使用 element.bind 并不好。只需添加 console.log 并查看在您输入时被调用了多少次。
  • 是的,我也想要添加零限制输入非数字字符
【解决方案2】:

指令代码运行通过您的 if 语句并返回“未定义”(因为没有 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;

      });
    }
  };
});

【讨论】:

    猜你喜欢
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多