【问题标题】:Directive to format text input does not work on initial values格式化文本输入的指令不适用于初始值
【发布时间】:2022-01-12 19:51:17
【问题描述】:

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

money-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 />

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

【问题讨论】:

  • 你试过ngAfterViewInit钩子吗?

标签: angular angular-directive


【解决方案1】:

在超时后移动格式:

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

这样它就会进入另一个摘要循环,这似乎使它起作用。

【讨论】:

  • 谢谢!我以前试过这个,但我认为我调用它的方式,ngModel 是空的。但是,只需将 formatCurrency() 中的代码包装在 setTimeout 中而没有指定延迟就可以了。
  • 太棒了,很高兴听到。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-10
  • 2020-12-19
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
  • 2011-10-17
  • 2016-07-24
相关资源
最近更新 更多