Угловой 2 ставит пробел между числами в соответствии с длиной числа

Я хочу поставить пробел между числами - например 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;
  }

Ожидаемое поведение:

  1. Если длина 4 - 1 000
  2. Если длина 5 - 10 000
  3. При длине 6 - 100 000 руб.
  4. Если длина 7 - 1 000 000

Результат моей функции:

Он считает length нормально - например, если 600000 (6 length), он делает часть if (p.length == 6), а после этого делает if (p.length == 7), потому что раньше в if (p.length == 6) он становился 7 с пробелом.

Как улучшить мою работу?

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

Rajeev Ranjan 04.01.2019 11:10

Вы можете использовать Intl.NumberFormat или toLocaleString, чтобы отобразить 5000000 как 5.000.000, а затем заменить расширение. с пробелами.

Kokodoko 04.01.2019 11:11

@Kokodoko Интересно, я никогда об этом не задумывался.

Alex Beugnet 04.01.2019 11:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
4 762
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Один из вариантов - использовать регулярное выражение: идентифицировать каждую позицию в строке так, чтобы за 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, я пытаюсь использовать ваш канал, когда я пытаюсь сохранить данные в бэкэнде, возникает ошибка, заключающаяся в том, что ввод не является допустимым двойником, есть ли способ решить эту проблему

Bilal Dekar 09.08.2020 16:15

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

Alex Beugnet 10.08.2020 03:19

спасибо @Alex, я преобразовал ввод в двойной, прежде чем отправить его, чтобы он сохранялся, и это сработало

Bilal Dekar 10.08.2020 11:16

есть что-то еще, когда я ввожу число с запятой, оно сохраняется отлично, но часть после запятой не отображается во вводе

Bilal Dekar 10.08.2020 11:17

Я могу задать вопрос, если хотите.

Bilal Dekar 10.08.2020 11:35

Похоже на проблему с HTML, может быть, размер ввода неверный?

Alex Beugnet 11.08.2020 23:18

Я понял это, возникла проблема с запятой, формат не принимает во внимание часть после запятой, поэтому я добавил value.slice (value.indexOf ('.') + 1, value.length); к окончательному результату

Bilal Dekar 12.08.2020 13:52

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