Я хочу поставить пробел между числами - например 600000 -> 600 000.
Что я сделал :
HTML:
<h2>{{price.spaces(item.price)}}€</h2>
TS:
spaces(price){
let p = new String(price);
if (p.length == 4){
p.split("", 4);
p = p[0] + ' ' + p[1] + p[2] + p[3];
}
if (p.length == 5){
p.split("", 5);
p = p[0] + p[1] + ' ' + p[2] + p[3] + p[4];
}
if (p.length == 6){
p.split("", 6);
p = p[0] + p[1] + p[2] + ' ' + p[3] + p[4] + p[5];
}
//if (p.length == 7){
//p.split("", 7);
//p = p[0] + ' ' + p[1] + p[2] + p[3] + ' ' + p[4] + p[5] + p[6];
//}
return p;
}
Ожидаемое поведение:
Результат моей функции:
Он считает length нормально - например, если 600000 (6 length), он делает часть if (p.length == 6), а после этого делает if (p.length == 7), потому что раньше в if (p.length == 6) он становился 7 с пробелом.
Как улучшить мою работу?
Вы можете использовать Intl.NumberFormat или toLocaleString, чтобы отобразить 5000000 как 5.000.000, а затем заменить расширение. с пробелами.
@Kokodoko Интересно, я никогда об этом не задумывался.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Один из вариантов - использовать регулярное выражение: идентифицировать каждую позицию в строке так, чтобы за 3 цифрами, или 6 цифрами, или 9 цифрами и т. д. Позже следовал конец строки:
const spaces = price => String(price)
.replace(
/(?!^)(?=(?:\d{3})+$)/g,
' '
);
for (let i = 1; i < 1e10; i *= 10) {
console.info(spaces(i));
}(?!^)(?=(?:\d{3})+$) означает:
(?!^) - отрицательный просмотр вперед для ^ - убедитесь, что эта позиция не является началом строки(?=(?:\d{3})+$) - Положительный прогноз для:
(?:\d{3})+ - Цифровые символы повторяются 3 раза$ - за ним следует конец строкиЯ создал специальный канал Angular для управления и отображения таких чисел с пробелом.
Цель состоит в том, чтобы иметь общий метод, который может преобразовывать один вход (число) и преобразовывать его в то, что я хочу (форматированное число). Угловые трубы производятся и отлично подходят для этого.
Вот образец, вы можете вдохновиться им и брать только то, что хотите.
Я использовал евклидово деление, чтобы управлять числами любой длины.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'formatNumber'
})
export class FormatNumberPipe implements PipeTransform {
transform(value: any): string {
if (value) {
// Gets the value as a string
if (typeof value !== 'string') {
value = value.toString();
}
// Delete existing spaces
while ((value as string).indexOf(' ') !== -1) {
value = (value as string).replace(' ', '');
}
// Manage decimal values
let integerPart: string = value;
if (value.indexOf('.') !== -1) {
integerPart = value.slice(0, value.indexOf('.'));
}
if (value.indexOf(',') !== -1) {
integerPart = value.slice(0, value.indexOf(','));
}
let firstSlice = true;
const arrayResults: Array<string> = [];
let finalResult = '';
const divisor = 3;
const dividend: number = integerPart.length;
let remainder = dividend % divisor;
let quotient = (dividend + remainder) / divisor;
if (dividend >= 3) {
do {
if (firstSlice && remainder > 0) {
// Manage numbers with remainders
firstSlice = false;
arrayResults.push(integerPart.slice(0, remainder));
} else {
// Slice each part of the number to an array
firstSlice = false;
arrayResults.push(integerPart.slice(remainder, remainder + divisor));
remainder = remainder + divisor;
quotient--;
}
// Continue dividing the number while there are values
} while (quotient >= 1);
// Concats the sliced parts to build the final number
arrayResults.forEach(part => {
finalResult += `${part} `;
});
// Delete any trailing whitespace
finalResult = finalResult.trim();
return finalResult;
} else {
return value;
}
}
return value;
}
}
Как только канал будет готов, вы можете использовать его, как хотите, в своем приложении:
Либо прямо в вашем шаблоне:
<input [ngModel] = "value | formatNumber" (ngModelChange) = "value = $event">
Или в вашем коде напрямую, используя Dependency Injection of the pipe:
this.sommeFormat.totalValue = this.formatNumber.transform(this.somme.totalValue);
Вот официальная документация по Angular pipe: https://angular.io/guide/pipes
Привет @Alex, я пытаюсь использовать ваш канал, когда я пытаюсь сохранить данные в бэкэнде, возникает ошибка, заключающаяся в том, что ввод не является допустимым двойником, есть ли способ решить эту проблему
Привет, так как вывод представляет собой строку, вам может потребоваться преобразовать ее обратно в двойную, прежде чем отправлять на бэкэнд. Вы можете легко сделать это, нарезав пробелы, а затем каким-то образом преобразовав строку в двойную. Так ваш бэкэнд должен работать правильно. Или вы также можете управлять им по-другому и отображать только преобразованное значение, а затем вместо этого отправлять на серверную часть исходное непреобразованное значение.
спасибо @Alex, я преобразовал ввод в двойной, прежде чем отправить его, чтобы он сохранялся, и это сработало
есть что-то еще, когда я ввожу число с запятой, оно сохраняется отлично, но часть после запятой не отображается во вводе
Я могу задать вопрос, если хотите.
Похоже на проблему с HTML, может быть, размер ввода неверный?
Я понял это, возникла проблема с запятой, формат не принимает во внимание часть после запятой, поэтому я добавил value.slice (value.indexOf ('.') + 1, value.length); к окончательному результату
вы можете посмотреть на директиву форматирования, особенно на валюту