AngularJS - 输入数字微调器,手动输入数字时无法正常工作

时间:2018-05-02 11:48:55

标签: angularjs directive

这里在stackoverflow上我找到了一个用户为angularJS做的指令,输入数字微调器,我只是在寻找它!

一切正常,但有一点不是,当你在输入栏中手动输入一个数字,然后按下MINUS,它会从那个数字中减去1,这里一切都很好,

但是当你输入一个数字时,首先按PLUS,而不是加1,它会在你写的数字旁边添加一个"1"! 只有“减去”才能修复它,

有人可以帮我修复代码以避免这种情况吗?我希望当我手动输入数字时,你可以按“加号”并获得该号码的+1

http://jsfiddle.net/Legendary/84qxvgm8/

1 个答案:

答案 0 :(得分:1)

那是因为input type="text"会返回一个字符串作为模型值,正如@AlekseySolovey所提到的那样 - 你必须将其转换为Number(因为"10" + 1会给出结果你“101”)。当你使用numericOnly指令时,它似乎是进行转换的正确位置,因为你只会在一个地方挥手。这是一个例子:

(function () {
    "use strict";

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

    app.controller('AppController', ['$scope', function ($scope) {
        var vm = this;

        vm.testNumber = 10;
    }]);

    app.directive('numericOnly', function () {
        return {
            require: 'ngModel',
            link: function (scope, element, attrs, modelCtrl) {

                modelCtrl.$parsers.push(function (inputValue) {
                    if (angular.isNumber(inputValue)) {
                        return inputValue;
                    }

                    var transformedInput = inputValue ? Number(inputValue.replace(/[^\d.-]/g, '')) : null;

                    if (transformedInput != inputValue) {
                        modelCtrl.$setViewValue(transformedInput);
                        modelCtrl.$render();
                    }

                    return transformedInput;
                });
            }
        };
    });

    app.directive('numberSpin', [function () {

        return {
            restrict: 'E',
            scope: {
                "ngModel": '='
            },
            template: '<div>' +
            '<input numeric-only data-ng-model="ngModel" ng-pattern="onlyNumbers" type="text">' +
            '<a class="ns-plus"  data-ng-click="plus()">+</a>' +
            '<a class="ns-minus"data-ng-click="minus()">-</a> </div>',
            link: function (scope, elem, attrs) {

                scope.onlyNumbers = /^\d+$/;

                scope.plus = function () {
                    scope.ngModel = scope.ngModel + 1;
                };

                scope.minus = function () {
                    scope.ngModel = scope.ngModel - 1;
                };

            }
        }

    }])


}());
number-spin div {
  position: relative;
  width: 126px;
  
}
number-spin input {
  height: 32px;
  width: 100%;
  text-align: right;
  padding-right: 20px;
  box-sizing: border-box;
  font-size: 16px;
}

number-spin .ns-plus {
  position: absolute;
  text-align: center;
  line-height: 16px;
  top: 0;
  right: 0;
  height: 16px;
  display: block;
  border-left: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  width: 16px;
}

number-spin .ns-minus {
  position: absolute;
  text-align: center;
  display: block;
  line-height: 16px;
  height: 16px;
  border-left: 1px solid #ccc;
  bottom: 0;
  right: 0;
  width: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<div ng-app="app" style="padding: 16px; "data-ng-controller="AppController as vm">


<number-spin data-ng-model="vm.testNumber"></number-spin>

</div>

更新:更简单的代码,允许将min / max传递到指令中:

(function () {
    "use strict";

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

    app.controller('AppController', ['$scope', function ($scope) {
        var vm = this;

        vm.testNumber = 10;
    }]);

    app.directive('numberSpin', [function () {

        return {
            restrict: 'E',
            scope: {
                "ngModel": '=',
                "min": '<',
                "max": '<',
                "step": '<'
            },
            template: '<div>' +
            '<input data-ng-model="ngModel" type="number" ng-attr-min="{{min}}" ng-attr-max="{{max}}">' +
            '<a class="btn ns-plus" data-ng-click="plus()">+</a>' +
            '<a class="btn ns-minus"data-ng-click="minus()">-</a> </div>',
            link: function (scope, elem, attrs) {

                scope.plus = function () {
                    if (scope.ngModel >= scope.max) return;
                    scope.ngModel += (scope.step || 1);
                    checkModel()
                };

                scope.minus = function () {
                    if (scope.ngModel <= scope.min) return;
                    scope.ngModel -= (scope.step || 1);
                    checkModel();
                };

                function checkModel() {
                    if (!scope.ngModel) scope.ngModel = scope.min || 0;
                }

            }
        }

    }])


}());
number-spin div {
    position: relative;
    width: 126px;

}

number-spin input {
    height: 32px;
    width: 100%;
    text-align: right;
    padding-right: 20px;
    box-sizing: border-box;
    font-size: 16px;
}

number-spin .btn {
    position: absolute;
    text-align: center;
    line-height: 16px;
    display: block;
    height: 16px;
    right: 0;
    border-left: 1px solid #ccc;
    width: 16px;
    cursor: pointer;
    user-select: none;
}

number-spin .ns-plus {
    top: 0;
    border-bottom: 1px solid #ccc;
    cursor: pointer;
    user-select: none;
}

number-spin .ns-minus {
    bottom: 0;
}

number-spin input[type=number]::-webkit-inner-spin-button,
number-spin input[type=number]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<div ng-app="app" style="padding: 16px; "data-ng-controller="AppController as vm">


<number-spin data-ng-model="vm.testNumber" min="0" max="15"></number-spin>

</div>