格式化文本输入的指令不适用于初始值

Directive to format text input does not work on initial values

我创建了一个指令来格式化文本输入中的货币。 blur 和 focus 事件有效,但如果 ngModel 中已经有一个值,它不会格式化数字。一旦你给予焦点并离开输入,它就会正确格式化。调试时,您可以看到模板在 ngOnInit 期间使用格式化值更新,但是当您单击继续时,该值不再格式化。

金钱-input.directive.ts

import { CurrencyPipe } from '@angular/common';
import {
  Directive,
  EventEmitter,
  HostListener,
  Injector,
  Input,
  Output,
} from '@angular/core';
import { NgControl, NgModel } from '@angular/forms';

@Directive({
  selector: '[moneyInput]',
  providers: [NgModel],
  host: {
    '(input)': 'onInputChange($event)',
  },
})
export class MoneyInputDirective {
  @Input() ngModel;
  @Output() ngModelChange: EventEmitter<any> = new EventEmitter();

  value: number;

  private control: NgControl;

  constructor(private currencyPipe: CurrencyPipe, private injector: Injector) {}

  ngOnInit() {
    this.control = this.injector.get(NgControl);

    if (!this.control || !this.control.valueAccessor) {
      return;
    }

    this.value = Number(this.ngModel);
    this.formatCurrency();
  }

  @HostListener('blur') onBlur() {
    this.formatCurrency();
  }

  @HostListener('focus') onFocus() {
    this.control.valueAccessor.writeValue(this.value);
  }

  onInputChange($event) {
    if (!isNaN(Number($event.target.value))) {
      this.value = Number($event.target.value);
    }

    this.ngModelChange.emit(this.value);
  }

  formatCurrency() {
    if (!isNaN(Number(this.ngModel))) {
      this.control.valueAccessor.writeValue(
        this.currencyPipe.transform(this.ngModel)
      );
    } else {
      this.control.valueAccessor.writeValue('');
    }
  }
}

app.component.html

<input type="text" [(ngModel)]="model" moneyInput />

Link 到 StackBlitz 项目 https://stackblitz.com/edit/angular-money-input-directive?file=src/app/app.component.html

将格式移到超时后:

      setTimeout(() => {
        this.control.valueAccessor.writeValue(
          this.currencyPipe.transform(this.ngModel)
        );
      })

因此它进入了另一个摘要周期,这似乎让它起作用了。