【问题标题】:Number pipe taking only three digits before decimal数字管道只取小数点前三位
【发布时间】:2021-08-10 19:02:26
【问题描述】:

我正在开发一个 Angular 应用程序。我有一个输入字段。我的代码如下

<input matInput style="width:100%;" type="number" [ngModel]="input | number : '1.2-2'" (ngModelChange)="input = $event"   autocomplete="off">

堆栈闪电战:

https://stackblitz.com/edit/ngx-slider-simple-slider-example-pl2peu?file=src%2Fapp%2Fapp.component.html

在这个输入字段中,我使用的是数字管道。我在使用数字管道时遇到的问题是,如果我在输入字段中输入一个数字,那么如果我尝试在十进制数字消失之前输入第 4 位数字,那么它只需要小数点前 3 位数字。我想允许用户在小数点前输入任意数量的数字。我该如何解决这个问题?

【问题讨论】:

标签: angular


【解决方案1】:

我认为您最好的选择是实现 ControlValueAccessor 并创建您自己的自定义表单控件,以您想要的方式格式化数据。这是一个类似的问题,接受的答案有一个自定义表单控件实现,应该让你走上正轨,

How to format number input in angular

【讨论】:

    【解决方案2】:

    其他选项以及 cmets

    您可以制作类似another SO 的东西。如果您在 .ts 焦点中有变量

    focus:boolean=false;
    

    你可以写一些像

    <input matInput style="width:100%;" type="number" 
       [ngModel]="focus?inputTarget:(inputTarget | number : '1.2-2')" 
       (ngModelChange)="inputTarget = $event"  
       (blur)="focus=false" 
       (focus)="focus=true"  autocomplete="off">
    

    或者你可以做一个指令

    @Directive({
      selector: '[format]',
      exportAs: 'child'
    })
    export class FormatDirective implements OnInit {
      focus:boolean=false;
      value:any;
      @Input('format') formato:string
      @HostListener('blur') _(){
        this.focus=false;
        this.value=this.control.control.value;
        this.control.control.setValue(formatNumber(this.value,'en-US',this.formato))
      }
      @HostListener('focus') __(){
        this.focus=true;
        this.control.control.setValue(this.value)
      }
      constructor(private control:NgControl){}
      ngOnInit(){
        setTimeout(()=>{
          this.value=this.control.control.value;
          this.control.control.setValue(formatNumber(this.value,'en-US',this.formato))
        })
      }
    }
    

    stackblitz

    注意:如果您“格式化”带有千位分隔符的数字,则类型不能是“数字”

    【讨论】:

    • 对于小数点前的值可以正常工作。但是一旦单击输入字段,它就会显示小数点后的所有值。您的解决方案中是否有任何方法可以将其限制为始终在小数点后两个值,无论我们是否单击它
    • 我添加了一个新答案,将这个答案和另一个关于面具的答案混合在一起。
    【解决方案3】:

    如果我们希望不允许超过 2 个小数,我们需要混合前面的答案和 this SO

    指令可以是这样的

    @Directive({
      selector: '[decimal]'
    })
    export class DecimalDirective implements OnInit {
      
      @Input('decimal') set _(value){
        this.formato=value;
        const digits=value.split('-')[1]
        this.regExpr=new RegExp("^[+-]?([1-9]\\d*|0)?(\\.\\d\{0,"+digits+"\})?$");
      }
      
      private formato:string=null
      private _oldvalue: string = "";
      private regExpr: any;
      private el: HTMLInputElement;
      private control:AbstractControl;
    
      constructor(private elementRef: ElementRef,private ngcontrol:NgControl,@Inject(LOCALE_ID) private language) {
        this.el = this.elementRef.nativeElement;
        this.control=ngcontrol.control
      }
      @HostBinding('style.text-align') get="right"
      @HostListener('input', ['$event'])
      change($event) {
    
        let item = $event.target
        let value = item.value;
        let pos = item.selectionStart;
        let matchvalue = value;
        let noMatch: boolean = (value && !(this.regExpr.test(matchvalue)));
        if (noMatch) {
          item.selectionStart = item.selectionEnd = pos - 1;
          if (item.value.length < this._oldvalue.length && pos == 0)
            pos = 2;
          this.el.value=this._oldvalue;
    
          item.value = this._oldvalue;
          this.control.setValue(item.value)
          item.selectionStart = item.selectionEnd = pos - 1;
        }
        else
        {
          this._oldvalue = value;
        }
      }
      @HostListener("focus", ["$event.target.value"])
      onFocus() {
        if (this.formato)
        this.el.value = this._oldvalue;
      }
    
      @HostListener("blur", ["$event.target.value"])
      onBlur(value: any) {
        if (this.formato)
        this.transform(value);
      }
      ngOnInit() {
        setTimeout(()=>{
          this.transform(this.control.value);
      
        })
      }
      
      transform(value: any) {
        this._oldvalue = value;
        if (value && !isNaN(value)) {
          this.el.value=formatNumber(+this._oldvalue, this.language, this.formato);
          const formated=this.el.value.split(',').join('')
          if (formated.indexOf(this._oldvalue) >= 0) this._oldvalue = formated;
        }
      }
    }
    

    你使用 as

    <input [(ngModel)]="value" decimal="1.2-2">
    

    the stackblitz

    【讨论】:

    • 这很好用。但是有没有可能我们可以在hmtl代码中处理相同的事情而不是单独的指令
    • @Julie,他的“key”在(模糊)不仅使“focus=false”,否则调用一个函数来改变 inputTarget 的方式只有两位小数:format() { this.inputTarget=Math.round(+this.inputTarget*100)/100 } 并使用@ 987654326@
    猜你喜欢
    • 2016-07-26
    • 2018-04-03
    • 1970-01-01
    • 2021-10-21
    • 2013-09-02
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多