AngularJS - спиннер числа, неправильно работающий при вводе числа вручную - PullRequest
0 голосов
/ 02 мая 2018

здесь, на stackoverflow, я нашел директиву, созданную пользователем для angularJS, для счетчика входных чисел, и я просто искал ее!

Все работает хорошо, но одно не так, когда вы вручную вводите число в поле ввода и нажимаете МИНУС, оно вычтет 1 из этого числа, все хорошо здесь,

но когда вы вводите число и первым делом нажимаете PLUS, вместо добавления 1, оно добавит "1" рядом с написанным вами числом! Только "минус" только однажды исправляет это,

Может кто-нибудь помочь мне исправить код, чтобы избежать этого? Я хочу, чтобы, когда я ставил номер вручную, вы можете нажать «плюс» и получить +1 на этот номер!

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

1 Ответ

0 голосов
/ 02 мая 2018

Это потому, что 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>
...