Угловая 8 пользовательских валютных масок - PullRequest
1 голос
/ 17 июня 2019

Прямо сейчас я делаю директиву маски валюты, которая должна быть совместима с угловыми реактивными формами. Вот мой Stabblitz https://stackblitz.com/edit/angular-8-currency-directive-insert.

В элементе ввода я ожидаю, что когда я введу 1, затем 2, затем 3, затем 4, затем 5, я бы увидел в консоли {currency: "$ 1,234"}, потому что маска запускает .substring (0, 4) однако я вижу {валюта: "$ 1,2345"}. Я вижу правильное отображаемое значение в $ 1234 внутри элемента ввода.

Если я изменю .substring (0,4) на .substring (0,3), тогда отображаемое значение в элементе ввода отображает 1,23 доллара, когда я ожидаю, что оно отобразит 1,234 доллара. Консоль выводит правильное значение {currency: "$ 1,234"}

Любые предложения, которые доходят до корня проблемы, очень приветствуются! Я уже поработал над обходом, который включает такие вещи, как разбиение на массив, проверка, удаление с конца и объединение, но эти исправления не идеальны. Любые предложения все еще приветствуются!

Спасибо за вашу поддержку.

Код, на котором следует сосредоточиться, находится в файле currency.directive.ts, указанном ниже:

 onInputChange(event, backspace) {
    let newVal = event.replace(/\D/g, '');
    if (newVal.length === 0) {
      newVal = '';
    } else if (newVal.length <= 3) {
      newVal = newVal.replace(/^(\d{0,3})/, '$1');
    // } else if (newVal.length <= 4) {
    //   newVal = newVal.replace(/^(\d{0,1})(\d{0,3})/, '$1,$2');
    } else {
      newVal = newVal.substring(0, 4);
      newVal = newVal.replace(/^(\d{0,1})(\d{1,3})/, '$1,$2');
    }
    this.ngControl.valueAccessor.writeValue("$"+ newVal);
    // console.log(this.toNumber(newVal))
  }

Ответы [ 2 ]

1 голос
/ 24 июня 2019

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

StackBlitz - Директива о формате валюты

Причины:

  • Мы не должны помещать символы валюты в наше значение $1,234
  • Мы должны отформатировать как пользовательские типы (безболезненный UX)
  • Мы должны сохранять наши значения валюты в виде необработанных чисел (полоса форматирование)
  • Мы не должны регулярное выражение для 3 символов, 4 символов, 5 символов и т. Д., Чтобы условно добавить форматирование (запятые или точки)

Вот что я сделал вместо этого. Я обрабатываю события paste, input и drop, но форматирование выполняется в getCurrencyFormat():

getCurrencyFormat(val) {
    // 1. test for non-number characters and replace/remove them
    const filtered = parseInt(String(val).replace(this.currencyChars, ''));

    // 2. format the number (add commas)
    const usd = this.decimalPipe.transform(filtered, '1.0');

    // 3. replace the input value with formatted numbers
    this.renderer.setProperty(this.el.nativeElement, 'value', usd);
}

Я считаю, что сохранение валюты должно осуществляться в необработанных числах. Поэтому в форме отправки я делаю это:

Number(this.form.get('currency').value.replace(/[^0-9]g/, ''));
1 голос
/ 19 июня 2019

Stackblitz https://stackblitz.com/edit/angular-8-currency-directive-insert-jdwx4b

пользовательский ввод валюты

import { Component, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-currency',
  template: '<input [(ngModel)]="value" (keyup)="setValue(value)">',
  styleUrls: ['./currency.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CurrencyComponent),
      multi: true
    }
  ]
})
export class CurrencyComponent implements ControlValueAccessor {

  value;

  constructor() {
  }

  setValue(event) {
    let newVal = event.toString().replace(/\D/g, '');
    if (newVal.length === 0) {
      newVal = '';
    } else if (newVal.length <= 3) {
      newVal = newVal.replace(/^(\d{0,3})/, '$1');
    } else {
      newVal = newVal.substring(0, 4);
      newVal = newVal.replace(/^(\d{0,1})(\d{1,3})/, '$1,$2');
    }
    newVal = '$' + newVal;
    if (newVal) {
      this.value = newVal;
      setTimeout(() => {
        // sometimes it needs a tick, specially first time
        this.propagateChange(this.value);
      });
    }
  }

  writeValue(value: any) {
    if (value !== undefined) {
      this.setValue(value);
    }
  }

  registerOnChange(fn) {
    this.propagateChange = fn;
  }

  registerOnTouched() {
  }

  propagateChange = (_: any) => {
  }

}

использование

<app-currency formControlName="currency"></app-currency>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...