2

我想在初始响应首次更新表单时格式化特定的输入字段,但我不知道如何进行初始格式化。

下面的例子是我尝试听的一种尝试ngModelChange。如果您在 FormControl 上设置值或输入不会取值,这将创建一个无限循环,但它使我想在父组件收到初始响应后更新格式。下面是我之后如何使用用户事件处理格式化,这很有效。

import { Directive, HostListener, ElementRef } from '@angular/core';
import { DecimalPipe } from '@angular/common';
import { FormGroup, NgControl } from '@angular/forms';

@Directive({
  selector: '[cfFloat]',
  providers: [DecimalPipe]
})
export class FloatDirective {
  public element: HTMLInputElement;

  constructor(
    private elementRef: ElementRef,
    private decimalPipe: DecimalPipe,
    private ngControl: NgControl
  ) {
    this.element = this.elementRef.nativeElement;
  }

  // ISSUE: this is not the proper event to listen to for a single 
  // initial formatting of any field with this directive, but I 
  // can't figure out how you would do the equivalent to this???
  @HostListener('ngModelChange', ['$event'])
  onModelChange(event: Event) {
    let value = this.element.value.replace(/[^\d\.]+/g, '');
    value = this.decimalPipe.transform(value, '1.2-2');
    //this.ngControl.control.setValue(value); // infinite loop, blows stack
    this.element.value = value; // prevents changes from being made
  }

  @HostListener('blur', ['$event'])
  onBlur(event: KeyboardEvent) {
    let value = this.element.value.replace(/[^\d\.]+/g, '');
    value = this.decimalPipe.transform(value, '1.2-2');
    this.element.value = value; // format for user, but don't change model
  }

  @HostListener('focus', ['$event'])
  onFocus(event: KeyboardEvent) {
    const input = event.target as HTMLInputElement;
    input.value = this.trim(input.value); // format for user, but don't change model
  }

}

现在我能想到做这样的事情的唯一方法是遍历页面中的所有输入以强制聚焦,让它们格式化,然后再次将表单设置为不受影响,这是一个可怕的解决方案。

4

1 回答 1

0

我最终使用valueChangesonNgControl然后在收到表单初始响应后取消订阅。valueChanges直到在 VSCode 中显示为 Observable时它才单击。

public ngOnInit() {
  const handle = this.ngControl.valueChanges
    .subscribe((value: string) => {
      this.element.value = this.decimalPipe.transform(value, '1.2-2');
      handle.unsubscribe();
    });
}
于 2017-04-29T22:29:55.690 回答