angular - 在 Angular 6 指令中格式化数字/货币

标签 angular format currency angular-directive

我创建了一个货币指令,我将在每个需要货币格式的输入元素中使用它。

所以我有 2 个主机监听器,一个是 OnFocus,第二个是 Blur

而且效果非常好。但是我通过绑定(bind)设置input的值时需要格式化input的值

因此,当我打开模式时,我会得到未格式化的值... NgOnInit 不起作用,因为它提前引发了太多

这是我的指令代码。

import { Directive, HostListener, Input, OnInit, ElementRef, AfterViewInit, OnChanges, Renderer2, ViewChild } from '@angular/core';

import { CurrencyPipe, getCurrencySymbol } from '@angular/common';

import { NgControl, ControlValueAccessor } from '@angular/forms';

import { CustomCurrencyPipe } from '../pipes/custom-currency.pipe';

import { ModalDirective } from 'ngx-bootstrap/modal';



@Directive({

  selector: '[appCurencyFormat]',

  providers: [CustomCurrencyPipe]

})



export class CurrencyFormatDirective implements OnInit{

  //@Input('appNumberFormat') params: any;

  @Input() decimalNumber: number = 2;

  @Input() symbol: string = "symbol";

  //@Input() OnlyNumber: boolean;

  local: string;

  decimal: string;

  currency: string;

  element: any;



  @ViewChild(ModalDirective) childModal: ModalDirective;



  constructor(private elementRef: ElementRef, private ngControl: NgControl, private currencyPipe: CustomCurrencyPipe, private _renderer: Renderer2) {


    this.element = this.elementRef.nativeElement;    

  }



  @HostListener('keydown', ['$event']) onKeyDown(event) {

    let e = <KeyboardEvent>event;

    //190 in array for .

      if ([46, 8, 9, 27, 13, 110].indexOf(e.keyCode) !== -1 ||

        // Allow: Ctrl+A

        (e.keyCode === 65 && (e.ctrlKey || e.metaKey)) ||

        // Allow: Ctrl+C

        (e.keyCode === 67 && (e.ctrlKey || e.metaKey)) ||

        // Allow: Ctrl+V

        (e.keyCode === 86 && (e.ctrlKey || e.metaKey)) ||

        // Allow: Ctrl+X

        (e.keyCode === 88 && (e.ctrlKey || e.metaKey)) ||

        // Allow: home, end, left, right

        (e.keyCode >= 35 && e.keyCode <= 39)) {

        // let it happen, don't do anything

        return;

      }

      // Ensure that it is a number and stop the keypress

      if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {

        e.preventDefault();

      }    

  }  



  @HostListener('focus', ['$event.target.value'])

  onFocus(value: any) {

    this.ctrl.setValue(this.currencyPipe.convertToNumber(value));    

  }



  @HostListener('blur', ['$event.target.value'])

  onBlur(value: any) {

    this.ctrl.setValue(this.currencyPipe.transform(value, this.decimalNumber, this.symbol));

  }



  get ctrl() {    

    return this.ngControl.control;

  }

}

我的解决方案是在 ngOnInit 中设置间隔...

ngOnInit() {
        let m = window.setInterval(() => {
        console.log("Upao sam");
        console.log(this.ctrl.value);
        if (this.ctrl.value) {
          console.log(this.ctrl.value);
          if (seted) {
            window.clearInterval(m);
          } else {
            seted = true;
            this.ctrl.setValue(this.currencyPipe.transform(this.ctrl.value, this.decimalNumber, this.symbol));
          }
        }
      }, 500);
}

有谁知道我可以使用哪个 HostListener,以避免使用 window.setInterval()。或者如果有人知道我该如何解决这个问题?

更新

ngOnChanges() 并非每次都会引发,因此所选的重复问题无法解决我的问题。

最佳答案

我会使用整个值访问器。这就是我所有输入所用的。你可以写这样的东西

@Component({
  selector: 'ks-input',
  template: `<input [(ngModel)]="value" />`,
  styleUrls: ['./whatever.component.css'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => InputComponent),
      multi: true
    }
  ]
})

export class InputComponent implements ControlValueAccessor {

  @Input('value') _value = '';
  onChange: any = () => {
  };
  onTouched: any = () => {
  };

  get value() {
    return this._value;
  }

  set value(val) {
    this._value = val;
    this.onChange(val);
    this.onTouched();
  }

  registerOnChange(fn) {
    this.onChange = fn;
  }

  registerOnTouched(fn) {
    this.onTouched = fn;
  }

  writeValue(value) {
    this.value = value;
  }
}

当您将变量传递给此组件时,它将首先通过 writeValue 函数,您可以在其中进行任何初始格式化。您还可以在每次值/输入 ngModel 变量更改时调用的设置值函数中执行任何操作。

关于angular - 在 Angular 6 指令中格式化数字/货币,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56964846/

相关文章:

ngIf-block 中可观察到的 Angular rxjs 错过第一次更新

angular - 导入两个同名的导出类

html - 在表中的 IE8 中显示多个表单提交按钮内联同一行

java - 日期格式不起作用?

iphone - iPhone-SDK中各个国家的 "currency decimal places width"

ios - 如何设置 NSNumberFormatter 以使用 "万"(日文/中文 10,000 标记)显示数字?

python - 将货币转换为 float (括号表示负数)

angular - RxJs 运算符、forkJoin 在 Angular 11 中显示超过 6 个参数的错误

angular - cdkDragHandle 在子组件中不起作用

c++ - C++中的cout浮点格式