角度 8 自定义货币掩码



现在我正在制作一个货币掩码指令,它应该与角度反应形式兼容。这是我的Stackblitz https://stackblitz.com/edit/angular-8-currency-directive-insert。

在输入元素中,我希望当我输入 1、2、3、4、然后 5 时,我会在控制台中看到 {货币:"$1,234"},因为掩码运行 .substring(0,4),但我看到 {货币:"$1,2345"}。 我在输入元素中看到正确的显示值 $1,234。

如果我将 .substring(0,4) 更改为 .substring(0,3),那么输入元素内的显示值显示 $1,23,而我希望它显示 $1,234。 控制台输出正确的值 {货币:"$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))
}

你的问题启发我创建了一个我会使用的货币指令。它不会像你那样接近这一点,但我相信它可以被用来代替或希望帮助他人。

堆栈闪电战 - 货币格式指令

原因:

  • 我们不应该把货币符号放在我们的价值$1,234
  • 我们应该格式化为用户类型(无痛用户体验)
  • 我们应该将我们的货币值保存为原始数字(条形 格式)
  • 我们不应该为 3 个字符、4 个字符、5 个字符等进行正则表达式以有条件地添加格式(逗号或点)

这是我所做的。 我处理pasteinputdrop事件,但格式化是在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/, ''));

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>

最新更新