角度 2:ngModel 输入"number"管道的光标问题



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

下面是我的代码:
<input [ngModel]="Amount | number: '1.2-2'" (ngModelChange)="updateAmount($event)" class="form-control" id="Amount" name="Amount" tabindex="4" type="number" autocomplete="off">

我遇到一些问题。

  1. 当我输入一个数字时,它会自动在末尾添加一个小数和两个0,这很好,但它也会将光标添加到末尾,所以如果我输入"55",而不是显示为"55.00",它显示为"5.01"(我假设它将其解释为5.005,然后将其舍入为5.01)。如何防止光标移到最后,以便用户可以自然地键入,同时看到他们期望的结果?
  2. 这个过滤器实际上并没有限制输入到小数点后2位。如果我输入"1234",它将显示为"1.00234"。还可以加上多个小数点。如何将其限制为一个小数点,后面只有2位数字?
  3. 输入错误很容易破坏这个管道。例如,如果用户输入一个字母,我将在控制台中得到一个错误,上面写着:

用于管道'DecimalPipe'的无效参数'11.00a'

出现此错误后,过滤器完全停止工作。

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

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

使用JQuery Inputmask给了我想要的限制/显示输入的结果,但它破坏了我的ngModel并将值设置为空,所以这不是我的选择,除非有人知道如何解决这个问题。

我可以改变我的管道得到我想要的结果吗?我怎样才能让它工作?

下面是前面提到的屏蔽输入的指令: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);
  }
}

输入元素看起来像:

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

检查最后一个字符是否为alpha或长度超过小数> 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);
      }
    }
  }

最新更新