【问题标题】:Angular How to Format Reactive FormControls Values after Invoking Patch Value on ngOnInitAngular 如何在 ngOnInit 上调用补丁值后格式化反应式 FormControls 值
【发布时间】:2017-09-27 03:36:27
【问题描述】:

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

下面的示例是我尝试收听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
  }

}

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

【问题讨论】:

    标签: angular angular-reactive-forms


    【解决方案1】:

    我最终在NgControl 上使用了valueChanges,然后在收到表单初始回复后取消订阅。它直到在 VSCode 中显示 valueChanges 是一个 Observable 时才点击。

    public ngOnInit() {
      const handle = this.ngControl.valueChanges
        .subscribe((value: string) => {
          this.element.value = this.decimalPipe.transform(value, '1.2-2');
          handle.unsubscribe();
        });
    }
    

    【讨论】:

    • 你可以使用像“this.ngControl.valueChanges.take(1)”这样的take操作符,你不需要取消订阅
    • 嗨。您是否在多个输入元素上使用该指令?因为我这样做了,当我更新(通过输入)只有一个输入时,所有输入都会调用this.ngControl.valueChanges。这是我的问题:stackoverflow.com/questions/50724559/…你能帮我解决这个问题吗?
    猜你喜欢
    • 1970-01-01
    • 2021-02-08
    • 2011-09-17
    • 2021-09-16
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    相关资源
    最近更新 更多