我以反应形式向字段添加了一个浮点指令,该指令将逗号添加到每 1000 个字段,并附.00
加到字段值,专门用于 UI 中的可读性,效果很好。
- onBlur 添加格式
- onFocus 删除格式
当表单加载现有值时,我希望对这些值进行格式化,因此我将其添加到我的浮点指令中,以便在使用setValue
or填充表单字段时对值进行一次格式化patchValue
,效果很好。
浮点指令的片段
public ngOnInit() {
this.formatFloat();
}
private formatFloat() {
const handle = this.ngControl.valueChanges
.subscribe((value: string) => {
const float = this.getFloat();
if (float) {
this.element.value = this.format(value);
}
handle.unsubscribe();
});
}
** 在下面添加了完整的指令,但这只是真正重要的部分。
但是,如果您在填写空表单时将表单字段动态添加到 FormArray,则不会触发一次性格式化,因此您在字段中键入的第一个数字会添加格式。例如,打开一个空表单,单击一个按钮以添加一个动态字段,1
在该字段中输入一次触发,valueChange
现在输入已经1.00
完成,用户将继续输入1.001244
而不是11244
.
我知道patchValue
并且通过文档setValue
直接链接到,但是有没有办法听或改变而不是听?或者有没有另一种方法可以让它工作,但仍然有现有的功能,因为即使只是听,也意味着一次性格式订阅仍然有效。valueChanges
emitEvent
setValue
patchValue
valueChanges
setValue
patchValue
浮点指令
import { Directive, HostListener, ElementRef, OnInit } from '@angular/core';
import { DecimalPipe } from '@angular/common';
import { FormGroup, NgControl } from '@angular/forms';
@Directive({
selector: '[cfFloat]',
providers: [DecimalPipe] // TODO: why do I need this?
})
export class FloatDirective implements OnInit {
public element: HTMLInputElement;
constructor(
private elementRef: ElementRef,
private decimalPipe: DecimalPipe,
private ngControl: NgControl
) {
this.element = this.elementRef.nativeElement;
}
@HostListener('blur', ['$event'])
onBlur(event: KeyboardEvent) {
const float = this.getFloat();
if (float) {
this.element.value = this.format(float);
}
}
@HostListener('focus', ['$event'])
onFocus(event: KeyboardEvent) {
const float = this.getFloat();
if (float) {
this.element.value = this.replace(float);
}
}
public ngOnInit() {
this.formatFloat();
}
private formatFloat() {
const handle = this.ngControl.valueChanges
.subscribe((value: string) => {
const float = this.getFloat();
if (float) {
this.element.value = this.format(value);
}
handle.unsubscribe();
});
}
private getFloat(): string {
const value = this.element.value;
const float = this.replace(value);
// Only perform an action when a floating point value exists and there are
// no errors, otherwise leave the erroneous value to be fixed manually by
// ignoring an action
if (value && float && this.checkIsValid()) {
return float;
}
}
private checkIsValid(): boolean {
return !this.ngControl.control.errors;
}
private replace(value: string): string {
return value.replace(/[^\d\.]+/g, '');
}
private format(value: string) {
return this.decimalPipe.transform(value, '1.2-2');
}
}