Удаление десятичного/центового фильтра валюты AngularJS

Есть ли способ удалить десятичные дроби/центы из вывода валютного фильтра? Я делаю что-то вроде этого:

<div>{{Price | currency}}</div>

Что выводит:

$1,000.00

Вместо этого я хотел бы:

$1,000

Можно ли это сделать с помощью фильтра валют? Я знаю, что могу добавить знак доллара к числу, и я мог бы написать свой собственный фильтр, но я надеялся, что существует простой метод с существующим фильтром валюты.

Спасибо.


person Mike Pateras    schedule 08.02.2013    source источник
comment
К сожалению нет. В валютном фильтре используется жестко закодированный вызов номера формата с использованием 2 знаков после запятой. Единственным решением на данный момент является добавление пользовательского фильтра   -  person Liviu T.    schedule 09.02.2013


Ответы (12)


Обновление: начиная с версии 1.3.0 - currencyFilter: добавьте FractionSize в качестве необязательного параметра, см. коммит и обновленный плункер

{{10 | currency:undefined:0}}

Обратите внимание, что это второй параметр, поэтому вам нужно передать undefined, чтобы использовать текущий символ валюты локали.

Обновление. Обратите внимание, что это работает только для символов валюты, которые отображаются перед числом. Начиная с версии 1.2.9 он по-прежнему жестко закодирован до 2 знаков после запятой.

Здесь представлена ​​модифицированная версия, в которой используется копия angular formatNumber для включения 0 FractionSize для валюты.


Обычно это должно быть настроено либо в определении локали, либо в вызове currencyFilter, но сейчас (1.0.4) это жестко закодировано до 2 знаков после запятой.

Пользовательский фильтр:

myModule.filter('noFractionCurrency',
  [ '$filter', '$locale',
  function(filter, locale) {
    var currencyFilter = filter('currency');
    var formats = locale.NUMBER_FORMATS;
    return function(amount, currencySymbol) {
      var value = currencyFilter(amount, currencySymbol);
      var sep = value.indexOf(formats.DECIMAL_SEP);
      if(amount >= 0) { 
        return value.substring(0, sep);
      }
      return value.substring(0, sep) + ')';
    };
  } ]);

Шаблон:

<div>{{Price | noFractionCurrency}}</div>

Пример:

Обновление: исправлена ​​ошибка при обработке отрицательных значений.

person Liviu T.    schedule 09.02.2013
comment
Это не работает с отрицательными значениями. {{ -1 | валюта }} = ($1,00), но {{ -1 | noFractionCurrency }} = ($1 - person Nikhil Dabas; 26.02.2013
comment
@NikhilDabas исправил это, хотя я думаю, что это больше связано с реализацией события фильтра валюты по умолчанию. - person Liviu T.; 26.02.2013
comment
Это не будет работать для локалей, где символ валюты стоит после числа. - person Ben Lesh; 16.01.2014
comment
@blesh Да, ты прав, это не сработает. Я поставлю это как предупреждение. - person Liviu T.; 16.01.2014
comment
@blesh Проблема в том, что angular не делает свою функцию formatNumber доступной, чтобы ее можно было использовать непосредственно для пользовательского форматирования валюты. - person Liviu T.; 16.01.2014
comment
Ну, я думаю, что если бы они просто добавили возможность установить точность числа, это также решило бы проблему. - person Ben Lesh; 16.01.2014
comment
Это настраиваемый фильтр plug and play - person Kyle Pennell; 16.11.2014

Вопрос кажется довольно старым, и данные ответы приятны. Однако есть еще одно альтернативное решение, которое также может помочь (которое я использую в своих проектах).

Это очень хорошо работает с префиксом символов валюты, а также с суффиксом числа для положительных и отрицательных значений.

Пользовательский фильтр:

angular.module('your-module', [])
    .filter('nfcurrency', [ '$filter', '$locale', function ($filter, $locale) {
        var currency = $filter('currency'), formats = $locale.NUMBER_FORMATS;
        return function (amount, symbol) {
            var value = currency(amount, symbol);
            return value.replace(new RegExp('\\' + formats.DECIMAL_SEP + '\\d{2}'), '')
        }
    }])

Шаблон:

<div>{{yourPrice| nfcurrency}}</div>

Примеры для разных локалей:

  • 10,00 (англ.-англ.) -> 10 фунтов стерлингов
  • 20.00 (en-us) -> 20$
  • -10.00 (en-us) -> (10$)
  • 30.00 (день-день) -> 30 крон
  • -30.00 (день-день) -> -30 крон

Пожалуйста, посмотрите демоверсию для долларов США и Датская крона.

Обновить

Обратите внимание, что этот обходной путь подходит для AngularJS 1.2 и более ранних выпусков библиотеки. Начиная с AngularJS 1.3, вы можете использовать форматер валюты. с третьим параметром, указывающим размер дроби - "Количество знаков после запятой для округления суммы".

Обратите внимание, что для использования формата валюты по умолчанию, полученного из локализации AngularJS, вам нужно будет использовать символ валюты (второй параметр), установленный на undefined (null или пусто НЕ будут работать). Пример в демонстрациях для долларов США и Датская крона.

person Tom    schedule 08.07.2013
comment
Большое спасибо, я предпочитаю этот, потому что он использует исходный $filter и исправляет только конечные десятичные знаки. - person stackular; 03.09.2013
comment
Это правильный ответ, так как он будет работать со всеми текущими языковыми стандартами... например, с французским швейцарским языком, в котором валюта указана после числа. - person Ben Lesh; 16.01.2014
comment
ПРИМЕЧАНИЕ. В этом есть небольшая ошибка: если десятичным разделителем является '.' или любой другой специальный символ регулярного выражения, его необходимо экранировать в строке RegExp. - person Ben Lesh; 16.01.2014
comment
@blesh, спасибо за ваш комментарий. Если вы посмотрите на эти регулярные выражения new RegExp('\\' + formats.DECIMAL_SEP + '\\d{2}'), первые \` characters are converted to the escape character. So in case of .` или даже + в качестве разделителей, вы получите такие регулярные выражения, как: /\.\d{2}/ или /\+\d{2}/ соответственно. - person Tom; 16.01.2014
comment
если по какой-то причине десятичный разделитель является "d", это сломается. - person Ben Lesh; 16.01.2014
comment
@blesh, ах да, в случае d механизм не будет работать (d станет \d и будет соответствовать только цифрам, а не букве d). Однако предложение было сделано с предположением, что Angular format.DECIMAL_SEP ограничен несколькими символами (например, ,, .) только во всех доступных культурах Angular. Но если вы будете использовать пользовательскую культуру, которая, например, использует d как DECIMAL_SEP, тогда этот механизм не будет работать должным образом. Спасибо - person Tom; 16.01.2014

Еще одна вещь, о которой стоит подумать, это то, что если вы знаете, что у вас есть только одна локаль или один тип валюты, вы можете поставить символ валюты перед числом, а затем использовать фильтр чисел, например (для валюты США).

  ${{Price | number:0}}

Более быстрое решение, если вы не хотите добавлять новый фильтр и иметь только одну валюту.

person JM Huret    schedule 18.12.2013
comment
Недостатком этого подхода является то, что отрицательные числа печатаются как -100 долларов, а не как (100) долларов. - person Andrew Thomas; 13.01.2014
comment
Это не полностью отвечает на вопрос, но решает мою проблему. - person Dr. C. Hilarius; 03.04.2017

Уже поздно, но может быть, это может помочь кому-то

{{value | currency : 'Your Symbol' : decimal points}}

Итак, давайте посмотрим несколько примеров с выводом

{{10000 | currency : "" : 0}}           // 10,000
{{10000 | currency : '$' : 0}}          // $10,000 
{{10000 | currency : '$' : 2}}          // $10,000.00 
{{10000 | currency : 'Rs.' : 2}}        // Rs.10,000.00
{{10000 | currency : 'USD $' : 2}}      // USD $10,000.00
{{10000 | currency : '#' : 3}}          // #10,000.000
{{10000 | currency : 'ANYTHING: ' : 5}} // ANYTHING: 10,000.00000

См. демонстрацию.

person Ali Adravi    schedule 12.04.2016

Это еще одно похожее решение, но оно удаляет десятичное число .00, но оставляет любое другое десятичное число.

$10.00 to $10

$10.20 to $10.20

app.filter('noFractionCurrency', [ '$filter', '$locale', function(filter, locale) {
    var currencyFilter = filter('currency');
    var formats = locale.NUMBER_FORMATS;
    return function(amount, currencySymbol) {
        amount = amount ? (amount*1).toFixed(2) : 0.00;
        var value = currencyFilter(amount, currencySymbol);
        // split into parts
        var parts = value.split(formats.DECIMAL_SEP);
        var dollar = parts[0];
        var cents = parts[1] || '00';
            cents = cents.substring(0,2)=='00' ? cents.substring(2) : '.'+cents; // remove "00" cent amount
        return dollar + cents;
    };
}]);
person Dustin    schedule 25.05.2014

Решение для угловой версии ‹ 1.3, если вы используете i18n, самый простой способ:

$filter('number')(x,0) + ' ' +$locale.NUMBER_FORMATS.CURRENCY_SYM;

Таким образом, у вас есть число, отформатированное с правильными разделителями и символом валюты в зависимости от локали.

person AndreiC    schedule 06.11.2014

Другое решение, которое удаляет конечные нули и находит правильный символ валюты для наиболее распространенных валют:

{{10.00|money:USD}} до 10 долларов США

{{10.00|money:EUR}} до €10

/**
 * @ngdoc filter
 * @name money
 * @kind function
 *
 * @description
 * Formats a number as a currency (ie $1,234.56), removing trailing zeros and using the     real currency symbol when possible. When no currency symbol is provided, default
 * symbol for current locale is used.
 *
 * @param {number} amount Input to filter.
 * @param {string=} symbol Currency symbol or identifier to be displayed.
 * @returns {string} Formatted number. *
 */
app.filter('money', [ '$filter', '$locale', function (filter, locale) {
var currencyFilter = filter('currency');
var formats = locale.NUMBER_FORMATS;

var getCurrencySymbol = function (code) {
    switch (code.toUpperCase()) {
        case 'EUR': //Euro
            return '€';

        case 'USD': //Dólar americano
        case 'MXN': //Peso mejicano
        case 'CAD': //Dólar de Canadá
        case 'AUD': //Dólar australiano
        case 'NZD': //Dólar neozelandés
        case 'HKD': //Dólar de Hong Kong
        case 'SGD': //Dólar de Singapur
        case 'ARS': //Peso argentino
            return '$';

        case 'CNY': //Yuan chino
        case 'JPY': //Yen japonés
            return '¥';

        case 'GBP': //Libra esterlina
        case 'GIP': //Libras de Gibraltar
            return '£';

        case 'BRL': //Real brasileño
            return 'R$';

        case 'INR': //Rupia india
            return 'Rp';

        case 'CHF': //Franco suizo
            return 'Fr';

        case 'SEK': //Corona sueca
        case 'NOK': //Corona noruega
            return 'kr';

        case 'KPW': //Won de Corea del Norte
        case 'KRW': //Won de Corea del Sur
            return '₩';

        default:
            return code;
    }
};

return function (amount, currency) {
    var value;
    if (currency) {
        value = currencyFilter(amount, getCurrencySymbol(currency));
    }
    else {
        value = currencyFilter(amount);
    }

    //Remove trailing zeros
    var regex = new RegExp("\\" + formats.DECIMAL_SEP + "0+", "i");
    return value.replace(regex, '');
};
} ]);
person Javier Marín    schedule 01.07.2014

И вот, если вы хотите округлить до ближайшей 1000 долларов: Прямая демонстрация:

var app = angular.module('angularjs-starter', []);

app.filter('noFractionRoundUpCurrency',
    [ '$filter', '$locale', function(filter, locale) {
      var currencyFilter = filter('currency');
      var formats = locale.NUMBER_FORMATS;
      return function(amount, currencySymbol) {
        var value = currencyFilter(amount, currencySymbol);
        var sep = value.indexOf(formats.DECIMAL_SEP);
        if(amount >= 0) { 
                    if (amount % 1000 < 500){
                        return '$' + (amount - (amount % 500));
                    } else {
                        return '$' + (amount - (amount % 500) + 500);          
                    }

        }
        else{
                    if (-amount % 1000 < 500){
                        return '($' + (-amount - (-amount % 500)) + ')';
                    } else {
                        return '($' + (-amount - (-amount % 500) + 500)+ ')';          
                    }
        }
      };
    } ]);

app.controller('MainCtrl', function($scope) {

});
person David Dehghan    schedule 21.06.2013

Именно то, что мне было нужно!

Я добавил условное выражение, чтобы полностью заменить валютный фильтр Angular и просто использовать модифицированную версию фильтра, показанную выше @Tom. Я уверен, что есть лучшие способы сделать это, но пока мне кажется, что это работает хорошо.


'use strict';
angular.module('your-module')
  .filter('nfcurrency', [ '$filter', '$locale', function ($filter, $locale) {
    var currency = $filter('currency'), formats = $locale.NUMBER_FORMATS;
    return function (amount, symbol) {
      var value = currency(amount, symbol), valArr = value.split(formats.DECIMAL_SEP);
      if(parseInt(valArr[(valArr.length - 1)]) > 0) {
        return value;
      } else {
        return value.replace(new RegExp('\' + formats.DECIMAL_SEP + '\d{2}'), '');
      }
    };
  }]);

person Smccullough    schedule 01.05.2014

Я немного изменил фильтр, опубликованный @Liviu T., чтобы принимать валюты с символом после числа и определенным количеством знаков после запятой:

app.filter('noFractionCurrency',
[ '$filter', '$locale', function(filter, locale) {
  var currencyFilter = filter('currency');
  var formats = locale.NUMBER_FORMATS;
  return function(amount, num, currencySymbol) {
    if (num===0) num = -1;
    var value = currencyFilter(amount, currencySymbol);
    var sep = value.indexOf(formats.DECIMAL_SEP)+1;
    var symbol = '';
    if (sep<value.indexOf(formats.CURRENCY_SYM)) symbol = ' '+formats.CURRENCY_SYM;
    return value.substring(0, sep+num)+symbol;
  };
} ]);

Например:

{{10.234 | noFractionCurrency:0}}
{{10.55555 | noFractionCurrency:2}}

Выходы:

$10
$10.56

Демо

person bertslike    schedule 15.07.2014
comment
Отрицательные числа, кажется, не работают. Последнее) удалено. - person Billy McKee; 08.08.2014

Если бы вы использовали angular-i18n (bower install angular-i18n), вы могли бы использовать декоратор, чтобы изменить значения по умолчанию в файлах локали, например:

$provide.decorator('$locale', ['$delegate',
  function ($delegate) {
    $delegate.NUMBER_FORMATS.PATTERNS[1].maxFrac = 0;
    $delegate.NUMBER_FORMATS.PATTERNS[1].minFrac = 0;
    return $delegate;
}]);

Обратите внимание, что это будет применяться ко всем фильтрам валют в вашем коде.

person Dormouse    schedule 03.02.2015

В Ангуляре 4+

{{totalCost | currency : 'USD' : 'symbol' : '1.0-0' }}
person Andrew Koper    schedule 19.09.2018