Как отформатировать числовой ввод в угловом формате

У меня есть такой числовой ввод Как отформатировать числовой ввод в угловом формате

и я хочу что-то вроде этого (не имеет значения, какой будет сепаратор)

Как отформатировать числовой ввод в угловом формате

Мой фактический код работает следующим образом:

<div class = "row center-xs" *ngFor = "let item of listItem;let i=index">
    <div class = "col-xs-12 col-md-10">
        <mat-form-field>
            <input [disabled] = "item.lock!=0" type = "number" matInput [placeholder] = "item.name" [(ngModel)] = "item.concept" >                                      
        </mat-form-field>
    </div>
</div>

Как я могу этого добиться?

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
9
0
10 361
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать «числовую» трубу Angular.

https://angular.io/api/common/DecimalPipe

Этот канал управляет цифрами дроби, а также форматированием числа в зависимости от языкового стандарта (по умолчанию: en-US).

Таким образом, число вроде: 2000000 будет преобразовано в 2,000,000. В зависимости от локали разделители будут разными.

@Component({
  selector: 'number-pipe',
  template: `
    <!--output '2,000,000'-->
    {{e | number}}
  `
})
export class NumberPipeComponent {
  e: number = 2000000;
}

В этом случае я не могу использовать канал, потому что я не использую числа, когда вы говорите, и я использую двустороннюю привязку на входе, а не только отправляю значение

Cesar Leonardo Ochoa Contreras 16.10.2018 03:53
Ответ принят как подходящий

У меня была похожая проблема. Чтобы решить эту проблему, я использовал этот статья. Я создал немного измененную версию под свои нужды.

import { Directive, ElementRef, forwardRef, HostListener, Input, OnDestroy } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { MAT_INPUT_VALUE_ACCESSOR } from '@angular/material';
import { Subscription } from 'rxjs';
import { formatNumber } from '@angular/common';

@Directive({
  selector: 'input[localizedNumericInput]',
  providers: [
    { provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: LocalizedNumericInputDirective },
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => LocalizedNumericInputDirective),
      multi: true
    }
  ]
})
export class LocalizedNumericInputDirective implements ControlValueAccessor, OnDestroy {
  locale = 'en';
  decimalMarker: string;

  constructor(private element: ElementRef<HTMLInputElement>) {
  }

  private _value: string | null;

  get value(): string | null {
    return this._value;
  }

  @Input('value')
  set value(value: string | null) {
    this._value = value;
    this.formatValue(value);
  }

  @HostListener('input', ['$event.target.value'])
  input(value) {
    //Find all numerics, decimal marker(, or .) and -
    //It will delete thousandSeparator cos it's always opposite to decimal marker
    const regExp = new RegExp(`[^\\d${this.decimalMarker}-]`, 'g');
    //Separate value on before and after decimal marker
    const [integer, decimal] = value.replace(regExp, '').split(this.decimalMarker);

    //Send non localized value, with dot as decimalMarker to API
    this._value = decimal ? integer.concat('.', decimal) : integer;

    // If decimal separator is last character don't update
    // because it will delete . || ,
    if (this.isLastCharacterDecimalSeparator(value)) {
      this._value = value;
    }

    // here to notify Angular Validators
    this._onChange(this._value);
  }

  @HostListener('blur')
  _onBlur() {
    /**
     * Adding thousand separators
     */
    this.formatValue(this._value);
  }

  @HostListener('focus')
  onFocus() {
    this.unFormatValue();
  }

  _onChange(value: any): void {}

  /**
   * @param value
   * apply formatting on value assignment
   */
  writeValue(value: any) {
    this._value = value;
    this.formatValue(this._value);
  }

  registerOnChange(fn: (value: any) => void) {
    this._onChange = fn;
  }

  registerOnTouched() {}

  isLastCharacterDecimalSeparator(value: any) {
    return isNaN(value[value.length - 1]);
  }


  private formatValue(value: string | null) {
    if (value === null) {
      this.element.nativeElement.value = '';
      return;
    }

    if (this.isLastCharacterDecimalSeparator(value)) {
      this.element.nativeElement.value = value;
      return;
    }

    // Conclude the decimal and thousand separators from locale
    const [thousandSeparator, decimalMarker] = formatNumber(1000.99, this.locale).replace(/\d/g, '');
    this.decimalMarker = decimalMarker;

    //Here value should always come with . as decimal marker thus any other behavior is bug
    const [integer, decimal] = value.split('.');

    //Group every three elements, and add thousandSeparator after them
    this.element.nativeElement.value = integer.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);

    //Add decimals and decimalMarker if any
    if (decimal) {
      this.element.nativeElement.value = this.element.nativeElement.value.concat(decimalMarker, decimal);
    }
  }

  private unFormatValue() {
    const value = this.element.nativeElement.value;
    if (this.isLastCharacterDecimalSeparator(value)) {
      return;
    }
    const regExp = new RegExp(`[^\\d${this.decimalMarker}-]`, 'g');
    const [integer, decimal] = value.replace(regExp, '').split(this.decimalMarker);

    this._value = integer.concat('.', decimal);
    if (value) {
      this.element.nativeElement.value = this._value;
    } else {
      this.element.nativeElement.value = '';
    }
  }
}

Ну, я забыл об этом вопросе на некоторое время и наконец решил его, разделив функции форматирования и привязку angular. Но такой подход с помощью директив намного точнее. Я отмечу это как принятый. Спасибо, что предоставили это решение, думаю, оно будет кому-то полезно

Cesar Leonardo Ochoa Contreras 10.02.2020 02:29

@ alexander-poshtaruk здесь настоящий герой :)

Radovan Skendzic 11.02.2020 15:16

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