如何在自定义属性指令中获取具有数字类型的输入值

How to get the value of an input with a type of number in a custom attribute directive

这是我目前在 IE 11 中实现和工作的内容,现在我们正在尝试摆脱 IE11 并修复一些弹出的问题。

 <input type="number" evaluate-input="model.personalNumber" ng-model="model.personalNumber" maxlength="50" ng-change="..." ng-blur="..." />
angular.module("myApp")
    .directive("evaluateInput", [
        function () {
            return {
                restrict: "A",
                replace: true,
                scope: {
                    evaluateInput: "="
                },
                link: function ($scope, elem, attrs, ctrl) {

                    /* Need to grab the input from the element because if the input is a number type and it has non-numeric values then the model will be empty. */
                    var inputValue;

                   
                    elem.bind("keyup", function (e) {

                        inputValue = elem[0].value;

                        if (e.keyCode === 13) {
                            $scope.$apply(function () {
                                calculateFormula();
                            });
                        }
                    })

                    elem.bind("blur change", function (e) {

                        inputValue = elem[0].value;

                        $scope.$apply(function () {
                            calculateFormula();
                        });

                    })

                    /* Uses the javascript eval function but catches and swallows any errors and returns null */
                    function calculateFormula() {

                        var result = null;

                        try {
                            result = eval(inputValue);

                            result = Number(result.toFixed(2));
                        }
                        catch (e) {
                            // No need to generate an error on invalid input.
                            // Just leave the result as null
                        }

                        $scope.ngModel = result;
                    }

                }
            };

        }]);

它的工作方式是你可以在输入中输入一个像 100*2 这样的表达式,它将计算表达式和 return 结果。当 运行 this in Edge 或 Chrome elem[0].value 没有设置值。

我尝试使用其他方法(例如 elem.val() 和 attr.evaluateInput 获取值,但这些方法要么是 return null 要么是模型名称。当这个指令被命中时,好像 ng-model 没有被设置。

任何正确方向的帮助或信息将不胜感激。

您的主要问题在于 HTML5 约束验证。

AngularJS documentation 中所述:

If a non-number is entered in the input, the browser will report the value as an empty string, which means the view / model values in ngModel and subsequently the scope value will also be an empty string.

为了解决这个问题,您必须将 input 设置为 text 输入。

我已经修复了这个问题以及以下示例中的其他一些小错误

const app = angular.module("myApp", []);

app.controller('TestCtrl', function() {

  const ctrl = this;

  ctrl.personalNumber = 2;
})

app.directive("evaluateInput", [
  function() {
    return {
      restrict: "A",
      scope: {
        ngModel: '='
      },
      link: function($scope, elem, attrs, ctrl) {

        /* Need to grab the input from the element because if the input is a number type and it has non-numeric values then the model will be empty. */
        var inputValue;

        elem.bind("keyup", function(e) {
          inputValue = elem[0].value;

          if (e.keyCode === 13) {
            calculateFormula();
          }
        })

        elem.bind("blur change", function(e) {

          inputValue = elem[0].value;

          calculateFormula();

        })

        /* Uses the javascript eval function but catches and swallows any errors and returns null */
        function calculateFormula() {

          var result = null;

          try {
            result = eval(inputValue);

            result = Number(result.toFixed(2));
          } catch (e) {
            // No need to generate an error on invalid input.
            // Just leave the result as null
          }

          $scope.ngModel = result;
        }

      }
    };

  }
]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.8/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="TestCtrl as model">

    <input type="text" evaluate-input ng-model="model.personalNumber" maxlength="50" />

    <div>
      {{model.personalNumber}}
    </div>

  </div>
</div>