如何在angular8中获取错误消息后获取转换为货币管道值的金额

如何在angular8中获取错误消息后获取转换为货币管道值的金额,angular,currency-pipe,Angular,Currency Pipe,我在模糊事件中使用货币管道。但它第一次运行良好,当我收到验证的错误消息时,如果我删除了几个数字并显示出来,它将不会被格式化为货币格式,仍然是用户删除的格式。 例如,我给出了这个数字: 36543265因此,当我从输入中出来时,它被格式化为$36543265.00,并显示验证错误消息。所以如果我删除 265.00从$36543265.00中,我仍然有错误验证消息。因此,验证错误消息关闭并保留此格式$36543,但格式不正确。在清除验证消息后,如何将其转换为正确的货币管道格式USD 如何根据用户删除

我在模糊事件中使用货币管道。但它第一次运行良好,当我收到验证的错误消息时,如果我删除了几个数字并显示出来,它将不会被格式化为货币格式,仍然是用户删除的格式。 例如,我给出了这个数字:
36543265
因此,当我从输入中出来时,它被格式化为
$36543265.00
,并显示验证错误消息。所以如果我删除
265.00
$36543265.00
中,我仍然有错误验证消息。因此,验证错误消息关闭并保留此格式
$36543
,但格式不正确。在清除验证消息后,如何将其转换为正确的货币管道格式
USD

如何根据用户删除的值使其正确格式化

TS:

HTML:


最多允许8个字符,包括$
演示:

插入$符号后,代码出现错误

您可以使用此正则表达式仅从文本中获取数字

var thenum=thestring.replace(/^\D+/g',);//将所有前导非数字替换为零


或者只需检查第一个字符,如果是$remove,则删除它

我已经更改了代码中的一些内容,以使其正常工作:

以下是主要部分:

public transformAmount(name) {
    let formattedAmount = this.currencyPipe.transform(
        this.eoInfoForm.value.amount.replace(/[^\d.E+]/gm, ""),
        "USD"
    );
    this.eoInfoForm.get(name).setValue(formattedAmount);
}
我所做的是在将值再次传递给管道之前反转管道变换。我使用
/[^\d.E+]/gm
正则表达式删除了未包含在以下内容中的所有内容:

  • 点字符
  • “E”字
  • “+”字符
“E”和“+”用于处理数字非常大的特定情况,显示方式为
$1.00E+37


我认为当文本格式化后,最大长度8是适用的,所以我没有碰它(否则你需要一个自定义验证器)。我刚刚将它移到了TypeScript文件中,因为您使用的是反应式表单,所以最好不要混合模板表单的概念。

您可以编写一个稍微简单的指令来执行此操作:

import { Directive, HostListener, ElementRef, OnInit, Input } from "@angular/core";
import { CurrencyPipe } from '@angular/common';

@Directive({ selector: "[currencyInput]" })
export class CurrencyInputDirective implements OnInit {

  // build the regex based on max pre decimal digits allowed
  private regexString(max?: number) {
    const maxStr = max ? `{0,${max}}` : `+`;
    return `^(\\d${maxStr}(\\.\\d{0,2})?|\\.\\d{0,2})$`
  }
  private digitRegex: RegExp;
  private setRegex(maxDigits?: number) {
    this.digitRegex = new RegExp(this.regexString(maxDigits), 'g')
  }
  @Input()
  set maxDigits(maxDigits: number) {
    this.setRegex(maxDigits);
  } 

  private el: HTMLInputElement;

  constructor(
    private elementRef: ElementRef,
    private currencyPipe: CurrencyPipe
  ) {
    this.el = this.elementRef.nativeElement;
    this.setRegex();
  }

  ngOnInit() {
    this.el.value = this.currencyPipe.transform(this.el.value, 'USD');
  }

  @HostListener("focus", ["$event.target.value"])
  onFocus(value) {
    // on focus remove currency formatting
    this.el.value = value.replace(/[^0-9.]+/g, '')
  }

  @HostListener("blur", ["$event.target.value"])
  onBlur(value) {
    // on blur, add currency formatting
    this.el.value = this.currencyPipe.transform(value, 'USD');
  }

  // variable to store last valid input
  private lastValid = '';
  @HostListener('input', ['$event'])
  onInput(event) {
    // on input, run regex to only allow certain characters and format
    const cleanValue = (event.target.value.match(this.digitRegex) || []).join('')
    if (cleanValue || !event.target.value)
      this.lastValid = cleanValue
    this.el.value = cleanValue || this.lastValid
  }
}
该指令将值转换为焦点上的数字,并在模糊时转换回格式化的货币字符串

使用类似于:

<input type="text" class="form-control" placeholder="Amount in dolars" autocomplete="off"
  formControlName="amount" currencyInput maxDigits="9" 
  [ngClass]="{ 'is-invalid': eoInfo.amount.dirty  && eoInfo.amount.invalid }">


闪电战:

我想指出的第一件事是:

您可以使用
maxlength=“8”
,这在您开始使用货币管道之前是可以的。您的货币管道添加的字符将被考虑在内。我不知道这是否是一种被通缉的行为,但从用户的角度来看,这绝对不是直观的

“我最多只能输入8个字符,最多可以输入8个字符”- 这是我在阅读验证信息时首先想到的。当我输入(当时)未格式化的数字时,我不想自己去想货币的格式化

我建议将
maxLength
14(8+1美元符号+2个逗号+1个点+两位数是USD=14个字符的最大可能数字),并将验证消息的值保留为8。或者,如果格式化后确实只需要8个字符,请将验证消息值设为3(3+1美元符号+1个逗号+1个点+两位数=7),4位数字在格式化后将变为9个字符,因为添加了额外的数字+一个逗号,将变为9个字符,这超过了最大长度8

您还可以对长度使用自定义验证,并正确检查自己(如果货币格式可能不同,这很好),而不是依赖通用的
*ngIf=“amt&&eoInfo.amount.invalid”


现在对于您的实际问题,我认为最好的解决方案是在编辑时删除格式。当用户在编辑时真正关心的是数字时,编辑和浏览
$
对他们来说从来都不实际。 当用户聚焦字段时,您可以制作一个“反向货币管道”,这样他们看到的就是数字

我对你的假设做了一个简单的解释,假设最大长度是指小数点之前的位数


如果有什么需要更改,请告诉我,这是否有助于解决您的问题。

我猜这只会在插入$后生效一次,代码无法再重新转换输入。.感谢您的回复。有没有其他方法可以满足此要求?@Bhrungarajni我给了您两个选项它对您有帮助吗?如果不让我知道,我可以提高我的answer@Bhrungarajni从你的问题来看,你真的不清楚你想要达到什么目标。1) 修改文本框非常糟糕。2) 您不能依赖于
maxlength
是否要格式化值-您需要一个自定义验证器。您能否在问题中清楚地重新说明验证规则?3) 为什么文本框需要格式化?这是用于用户输入的,应该验证为纯值。感谢您的回复,我应该在哪里添加该模式,您能在我的演示中编辑吗?我尝试了两种方法,并且在我的演示中,您能纠正我吗???@Bhrungarajni,无意冒犯,但在这种情况下,“规范答案”的含义类似于:“嘿,从头开始重写我的应用程序,修复所有损坏的角度指南“:)这里可以找到与上述建议类似的非常热的修复程序:感谢您的回复,但这里不允许我编辑值,例如,我键入了123.56,它是$123.56,现在我想编辑一些内容,所以我在中间尝试删除2并给出7,我可以删除2但无法添加7感谢您的回复,但由于
appTwoDigitDecimaNumber
指令,我无法编辑/添加某些内容。您想以数字格式或货币格式进行编辑?一切都可以,但我编辑的内容必须反映您想让我编辑我的解决方案吗
import { Directive, HostListener, ElementRef, OnInit, Input } from "@angular/core";
import { CurrencyPipe } from '@angular/common';

@Directive({ selector: "[currencyInput]" })
export class CurrencyInputDirective implements OnInit {

  // build the regex based on max pre decimal digits allowed
  private regexString(max?: number) {
    const maxStr = max ? `{0,${max}}` : `+`;
    return `^(\\d${maxStr}(\\.\\d{0,2})?|\\.\\d{0,2})$`
  }
  private digitRegex: RegExp;
  private setRegex(maxDigits?: number) {
    this.digitRegex = new RegExp(this.regexString(maxDigits), 'g')
  }
  @Input()
  set maxDigits(maxDigits: number) {
    this.setRegex(maxDigits);
  } 

  private el: HTMLInputElement;

  constructor(
    private elementRef: ElementRef,
    private currencyPipe: CurrencyPipe
  ) {
    this.el = this.elementRef.nativeElement;
    this.setRegex();
  }

  ngOnInit() {
    this.el.value = this.currencyPipe.transform(this.el.value, 'USD');
  }

  @HostListener("focus", ["$event.target.value"])
  onFocus(value) {
    // on focus remove currency formatting
    this.el.value = value.replace(/[^0-9.]+/g, '')
  }

  @HostListener("blur", ["$event.target.value"])
  onBlur(value) {
    // on blur, add currency formatting
    this.el.value = this.currencyPipe.transform(value, 'USD');
  }

  // variable to store last valid input
  private lastValid = '';
  @HostListener('input', ['$event'])
  onInput(event) {
    // on input, run regex to only allow certain characters and format
    const cleanValue = (event.target.value.match(this.digitRegex) || []).join('')
    if (cleanValue || !event.target.value)
      this.lastValid = cleanValue
    this.el.value = cleanValue || this.lastValid
  }
}
<input type="text" class="form-control" placeholder="Amount in dolars" autocomplete="off"
  formControlName="amount" currencyInput maxDigits="9" 
  [ngClass]="{ 'is-invalid': eoInfo.amount.dirty  && eoInfo.amount.invalid }">