角2:带有“数字”的光标问题。 ngModel输入上的管道 [英] Angular 2: Cursor issue with "number" pipe on ngModel input

查看:84
本文介绍了角2:带有“数字”的光标问题。 ngModel输入上的管道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an input that I want to be displayed like currency. I want only two decimal places to be allowed and for it to only allow numbers while automatically adding commas when necessary. Basically, if the user types "12345", I want the input to automatically display as "12,345.00". "12,345" would be acceptable too, but if they type in "12345.5" then it would need to be displayed as "12,345.50". I'm trying to use pipes to accomplish this and decided to use the "number" pipe since I don't want a currency symbol shown (I already have a dollar sign as a label before the input).

这是我的代码:

<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. 此过滤器实际上并没有将输入限制为两位小数。如果输入 1234,它将显示为 1.00234。它还将允许我添加多个小数点。如何将其限制为只有两位小数的小数点?

  3. 使用错误的输入来打破此管道确实很容易。例如,如果用户输入字母,我将在控制台中看到类似以下内容的错误:




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

Invalid argument '11.00a' for pipe 'DecimalPipe'

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

After this error, the filter completely stops working.

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

If I set the input to type="number" and I type in 1234, the value will be 1,234, but the input will disappear and I will get the following message in my console:


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

The specified value "1,234" is not a valid number. The value must match to the following regular expression: -?(\d+|\d+.\d+|.\d+)([eE][-+]?\d+)?

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

Using JQuery Inputmask gives me the results I want in terms of restricting/displaying the input, but it breaks my ngModel and sets the value to empty, so that isn't an option for me unless someone knows a way around that.

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

Are there changes I can make to my pipe to get me the results I want? How can I get this to work?

推荐答案

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

Here is the aforementioned inspired directive for masking the input: 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">

检查后卫字符是否为字母或长度超过小数的数字> 2:

Check guard if last character is alpha or length past decimals > 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);
      }
    }
  }

这篇关于角2:带有“数字”的光标问题。 ngModel输入上的管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆