26

我正在尝试使用http://jquerypriceformat.com/为欧盟货币字段创建输入掩码

到目前为止,在我的指令中,输入正确显示给应用了掩码的用户,但我认为有问题,因为 POST 值以奇怪的格式发送,与我们在输入字段中看到的完全不同。

我包括 priceformat.js

<script src="js/jquery.price_format.1.8.min.js"></script>

<input type="text" currency-input ng-model...>

在角度上:

app.directive('currencyInput', function() {
    return {
      require: '?ngModel',
      link: function($scope, element, attrs, controller) {
        element.priceFormat({
            prefix: '',
            centsSeparator: ',',
            thousandsSeparator: '.'
        });
      }
    };
});

我的输入正确显示了带有掩码的值,但是在 POST 数据(由角度调用)上它是一个不同的值,我错过了什么?

输入 > 2.200,80 | 帖子 > 22,0080

谢谢

4

5 回答 5

32

从您的示例中,我看不到该链接返回了某些内容。

我会写类似的指令:

.directive('format', ['$filter', function ($filter) {
    return {
        require: '?ngModel',
        link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;


            ctrl.$formatters.unshift(function (a) {
                return $filter(attrs.format)(ctrl.$modelValue)
            });


            ctrl.$parsers.unshift(function (viewValue) {

          elem.priceFormat({
            prefix: '',
            centsSeparator: ',',
            thousandsSeparator: '.'
        });                

                return elem[0].value;
            });
        }
    };
}]);

演示 1Fiddle

在此处输入图像描述

如果您想启动过滤器,请使用$formatters

现在link是:

link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;

            var format = {
                    prefix: '',
                    centsSeparator: ',',
                    thousandsSeparator: ''
                };

            ctrl.$parsers.unshift(function (value) {
                elem.priceFormat(format);

                return elem[0].value;
            });

            ctrl.$formatters.unshift(function (value) {
                elem[0].value = ctrl.$modelValue * 100 ;
                elem.priceFormat(format);
                return elem[0].value;
            })
        }

演示 2Fiddle

于 2013-10-24T21:13:48.193 回答
17

将 a 推$parser送到控制器,并且仅在它与使用的输入不匹配时更新值$setViewValue()and $render()

app.directive('currencyInput', function() {
    return {
      require: '?ngModel',
      link: function($scope, element, attrs, controller) {
        return ctrl.$parsers.push(function(inputValue) {

            ...

            if (result != inputValue) {
                controller.$setViewValue(res);
                controller.$render();
            }
        });
      }
    };
});

这是我用于货币输入指令的逻辑的小提琴:小提琴

于 2013-12-03T16:16:45.237 回答
4

派对迟到了,但我相信这值得另一个答案!我一直在使用ng-currency模块。这真是太棒了。

于 2016-09-02T13:46:46.100 回答
1

我喜欢 Dubilla 的方法,因为它简单而优雅。我决定在它上面添加一些功能(加上应有的功劳),使其非常接近现实世界的用例。

我在 github 项目中使用它来创建一些有用的财务指令github

显着的额外功能:

  1. 它对输入进行一些严格的检查以给出有效的响应。
  2. 它有一些键盘快捷键可以更快地输入大数字。
  3. 我展示了如何将它与 bootstrap 和 ngmodel css 更新集成。
  4. 作为奖励,我将表单的 ngmonel 输出为 JSON,以帮助人们实时了解表单验证的工作原理

它还使用 POJO 作为 ngmodel:

function Money() {
    this.notional = 0;
    this.maxValue = 99999999999.9;
    this.maxValueString = "99,999,999,999.9";
    this.maxPrecision = 10;
}

您可以将它与 Bootstrap 3 一起使用,如下所示:

<h1>Currency Formatting directive</h1>

<div class="row">

    <div class="col-md-6">
        <form name="myForm">

            <div class="form-group" ng-class="{'has-error': myForm.notional.$invalid && myForm.notional.$touched}">
                <input type="text" ng-model="myForm.money.notional  " money="money" money-input size="30" required
                       name="notional"
                       class="form-control"
                       placeholder="Enter notional amount"/>

                      <p class="help-block error" ng-show="myForm.notional.$error.required && myForm.notional.$touched">Required</p>



            </div>

            <button ng-disabled="myForm.$invalid" type="submit">SAVE</button>
        </form>
        <h2>Tips</h2>
        <ol>

            <li> Entering 'k' will multiply the amount by one thousand</li>
            <li> Entering 'm' will multiply the amount by one million</li>
            <li> Entering 'b' will multiply the amount by one billion</li>
        </ol>
    </div>
</div>
<p>Form debugger</p>
<pre>
               form = {{ myForm | json }}
    </pre>
于 2014-10-10T12:47:42.133 回答
0

这是一种不使用 jQuery 仅使用 Angular 指令来处理此问题的方法。此示例不支持小数。很容易修改它以支持它,只需更改函数$filter中的toView()

在我看来,这是解决相同问题的更好方法,因为您可以避免加载 jQuery 和作者提到的货币插件。使用属性应该支持对欧元的语言环境支持$locale,但我只测试了它以使用美元。

(function() {
  var app = angular.module('currencyMask', []);

  // Controller
  app.controller('ctrl', ['$scope', function($scope) {
    $scope.amount = 100000;
  }]);

  // Directive
  app.directive('inputCurrency', ['$locale', '$filter', function($locale, $filter) {

    // For input validation
    var isValid = function(val) {
      return angular.isNumber(val) && !isNaN(val);
    };

    // Helper for creating RegExp's
    var toRegExp = function(val) {
      var escaped = val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
      return new RegExp(escaped, 'g');
    };

    // Saved to your $scope/model
    var toModel = function(val) {

      // Locale currency support
      var decimal = toRegExp($locale.NUMBER_FORMATS.DECIMAL_SEP);
      var group = toRegExp($locale.NUMBER_FORMATS.GROUP_SEP);
      var currency = toRegExp($locale.NUMBER_FORMATS.CURRENCY_SYM);

      // Strip currency related characters from string
      val = val.replace(decimal, '').replace(group, '').replace(currency, '').trim();

      return parseInt(val, 10);
    };

    // Displayed in the input to users
    var toView = function(val) {
      return $filter('currency')(val, '$', 0);
    };

    // Link to DOM
    var link = function($scope, $element, $attrs, $ngModel) {
      $ngModel.$formatters.push(toView);
      $ngModel.$parsers.push(toModel);
      $ngModel.$validators.currency = isValid;

      $element.on('keyup', function() {
        $ngModel.$viewValue = toView($ngModel.$modelValue);
        $ngModel.$render();
      });
    };

    return {
      restrict: 'A',
      require: 'ngModel',
      link: link
    };
  }]);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>

<div ng-app="currencyMask" ng-controller="ctrl">
	<input input-currency ng-model="amount">
	<p><strong>Amount:</strong> {{ amount }}</p>
</div>

于 2017-08-18T19:51:55.000 回答