Как я могу отформатировать число как деньги в AMP-HTML?

У меня есть произвольное число, которое в моем сценарии использования составляет от 1000 до 1000000. Мне нужно отформатировать это значение в отображаемое значение, в котором оно отображается в виде денег. Т.е. 1000 -> "$1,000", 100000 ->"$100,000", так далее.

У меня проблема в том, что размер моего выражения слишком велик, а выражения AMP слишком ограничены, поэтому отформатировать числа не так просто, как я хотел. Я не могу использовать ".replace()" или любое другое регулярное выражение, и даже использование базовых условных выражений кажется чрезмерно сложным (не похоже, что я даже могу использовать стандартный троичный оператор: a? B:c;).

Вот что у меня

  //tells me how many digits i have
  amp-bind-macro#getLog10(arguments="num" expression="num.length - 1")

  //determines if the number should have a comma after it
  amp-bind-macro#numShouldHaveComma(arguments="log10" expression="log10%3==0 && log10!=0")

  //function to be invoked by Array.map()
  amp-bind-macro#formatNumber_map(arguments="char, ind, num" expression="(numShouldHaveComma(getLog10(round(num).toString().substr(ind+1))) && char+',') || char")

  //main formatter function (1000 -> 1,000)
  amp-bind-macro#formatNumber(arguments="num" expression="round(num).toString().split('').map((char,ind)=>formatNumber_map(char,ind, num)).join('')" )

  //adds $ and calls the formatter
  amp-bind-macro#formatMoney(arguments="val" expression="'$'+formatNumber(val)")

У меня есть элемент отображения, установленный для вызова formatMoney при изменении значения ползунка, например

<input type='range' on="input-throttled:AMP.setState({state:{mySlider:{value:event.value}}})" /> 

а также

<div id='display-money' [text]="formatMoney(state.mySlider.value)">$1,000</div>

Этот конкретный способ сделать это оставляет мне размер стека 53, что больше, чем допустимый максимум 50.

Причина я делаю round(num).toString() в том, что я, кажется, получаю противоречивые типы - иногда это число, а иногда строка. Таким образом, тип всегда анализируется правильно, и никаких ошибок не выдается.

Есть ли более простой способ отформатировать число, чтобы оно выглядело как деньги (целые доллары, разделенные запятыми тысячами)? Если нет, что я могу сделать с моим существующим кодом, чтобы он работал?

Спасибо!

1 ответ

Решение, которое я придумал, заключается в следующем.

//determines how many "0's" there are.
amp-bind-macro#getLog10(arguments="num" expression="num.length - 1")

//determines if the number should have a comma after it
amp-bind-macro#numShouldHaveComma(arguments="log10" expression="log10%3==0 && log10!=0")

//helper function for formatNumber
amp-bind-macro#formatNumber_map(arguments="char, ind, numStr" expression="(numShouldHaveComma(getLog10(numStr.substr(ind)))) ? char+',' : char")

//main number formatter
amp-bind-macro#formatNumber(arguments="num, numStr" expression="numStr.split('').map((char,ind)=>formatNumber_map(char,ind, numStr)).join('')" )

//adds "$" and calls formatNumber
amp-bind-macro#formatMoney(arguments="val" expression="'$'+formatNumber(round(val), round(val).toString())")

По сути, я упростил выражение, явно передав число как число и строку следующей функции, так что мне не нужно вызывать round(num).toString() в каждом отдельном макросе, только первый,

Для вашего целочисленного случая formatNumber, предлагаю более компактную реализацию, в одном amp-bind-macro:

<amp-bind-macro id="formatNumber" arguments="value" expression="(value<0?'-':'')+(abs(value)||0).toFixed().split('').map((v,i,a)=>(i&&(a.length-i)%3==0?',':'')+v).join('')"></amp-bind-macro>

Если значения â € â € ‹только положительные, (value<0?'-':'')+ с начала expression можно удалить.

Полный вариант с десятичными знаками я разместил здесь.

Другие вопросы по тегам