格式化文本输入的指令不适用于初始值
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)
);
})
因此它进入了另一个摘要周期,这似乎让它起作用了。
我创建了一个指令来格式化文本输入中的货币。 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)
);
})
因此它进入了另一个摘要周期,这似乎让它起作用了。