Angular 2:ngModel输入上的“数字”管道出现光标问题

Bre*_*ett 5 angular2-pipe angular

我有一个要显示为货币的输入。我只允许小数点后两位,并且只允许数字,并在必要时自动添加逗号。基本上,如果用户键入“ 12345”,我希望输入自动显示为“ 12,345.00”。“ 12,345”也是可以接受的,但是如果他们输入“ 12345.5”,则需要显示为“ 12,345.50”。我试图使用管道来完成此操作,并决定使用“数字”管道,因为我不想显示货币符号(输入之前我已经有一个美元符号作为标签)。

这是我的代码:

<input [ngModel]="Amount | number: '1.2-2'" (ngModelChange)="updateAmount($event)" class="form-control" id="Amount" name="Amount" tabindex="4" type="number" autocomplete="off">
Run Code Online (Sandbox Code Playgroud)

我有一些问题。

  1. 当我键入数字时,它会自动在末尾添加一个小数和两个0,这很好,但是它还会在其末尾添加光标,因此,如果我键入“ 55”,而不是显示为“ 55.00” ,则显示为“ 5.01”(我假设它将解释为5.005,然后将其四舍五入为5.01)。如何防止光标移到最末端,以便用户可以在看到期望结果的同时自然键入?
  2. 该过滤器实际上并没有将输入限制为两位小数。如果输入“ 1234”,它将显示为“ 1.00234”。它还将允许我添加多个小数点。如何将其限制为只有小数点后两位的小数点?
  3. 用不正确的输入来打破这个管道真的很容易。例如,如果用户输入字母,我将在控制台中看到如下错误:

管道'DecimalPipe'的无效参数'11 .00a'

发生此错误后,过滤器将完全停止工作。

如果将输入设置为,type="number"并输入1234,则值将为1,234,但是输入将消失,并且我将在控制台中收到以下消息:

指定的值“ 1,234”不是有效数字。该值必须与以下正则表达式匹配:-?(\ d + | \ d +。\ d + |。\ d +)([eE] [-+]?\ d +)?

使用JQuery Inputmask在限制/显示输入方面给了我想要的结果,但是它破坏了ngModel并将值设置为空,因此这对我来说不是一个选择,除非有人知道解决方法。

我可以对管道进行一些更改以获得我想要的结果吗?我该如何工作?

sil*_*sod 3

这是前面提到的用于屏蔽输入的启发指令: https://plnkr.co/edit/aBvO2F ?p=preview

import { Directive } from "@angular/core";
import { NgControl } from "@angular/forms";

@Directive({
  selector: '[ngModel][decimal]',
  host: {
    '(ngModelChange)': 'onInputChange($event)'
  }
})
export class DecimalMask {
  constructor(public model: NgControl) {}

  onInputChange(event, backspace) {
    var valArray = event.toString().split('.') : [];
    for(var i = 0; i < valArray.length; ++i) {
      valArray[i] = valArray[i].replace(/\D/g, '');
    }

    var newVal: number;

    if(valArray.length === 0) {
      newVal = '';
    }
    else {
      let matches = valArray[0].match(/[0-9]{3}/mig);

      if(matches !== null && valArray[0].length > 3) {
        let commaGroups = Array.from(Array.from(valArray[0]).reverse().join('').match(/[0-9]{3}/mig).join()).reverse().join('');
        let replacement = valArray[0].replace(commaGroups.replace(/\D/g, ''), '');

        newVal = (replacement.length > 0 ? replacement + "," : "") + commaGroups;
      } else {
        newVal = valArray[0];
      }

      if(valArray.length > 1) {
        newVal += "." + valArray[1].substring(0,2);
      }
    }
    // set the new value
    this.model.valueAccessor.writeValue(newVal);
  }
}
Run Code Online (Sandbox Code Playgroud)

输入元素如下所示:

<input decimal [(ngModel)]="Amount"
    class="form-control" id="Amount" name="Amount" tabindex="4" autocomplete="off">
Run Code Online (Sandbox Code Playgroud)

检查守卫最后一个字符是否为字母或小数点后的长度 > 2:

ngDoCheck() {
    console.log(this.Amount);
    if(this.Amount) {
      this.Amount = this.Amount.replace(/[A-Za-z]/g, '');
      if(this.Amount.indexOf('.') !== -1) {
        var arrayVals = this.Amount.split('.');
        this.Amount = arrayVals[0] + "." + arrayVals[1].slice(0,2);
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)