import { Component, Input, forwardRef, OnChanges } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'formatted-currency-input',
templateUrl: '../views/formattedCurrencyInput.component.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => FormattedCurrencyInputComponent),
multi: true
}
],
styles: ['.formatted-input {text-align: right; height: 100%; border: none; padding-right: 5px;}']
})
export class FormattedCurrencyInputComponent implements ControlValueAccessor {
@Input()
private _stringValue: string;
//private _stringValue: string;
@Input()
private _numberValue: number;
textVisible: boolean = false;
get numberValue() {
return this._numberValue;
}
set numberValue(val: number) {
this._numberValue = val;
this.propagateChange(this._numberValue);
}
get stringValue() {
return this._stringValue;
}
set stringValue(val: string) {
this._stringValue = val;
this.propagateChange(this._stringValue);
}
setValue(e: any) {
let val = e.target.value;
this._numberValue = parseInt(val);
this.convertToString(this._numberValue);
this.propagateChange(this._stringValue);
}
toggleActive() {
this.textVisible = !this.textVisible;
//console.log(input);
//input.focus();
}
convertToString(num: any) {
this._stringValue = parseFloat(num).toLocaleString();
}
/*
* Writes a new value from the form model into the view
* or (if needed) Dom property
*/
writeValue(obj: any) {
// Only set the value when it is not undefined
if (obj !== undefined) {
this.convertToString(obj);
}
}
propagateChange = (_: any) => {};
/*
* Method that registers a handler that should be called when
* something in the view has changed. It gets a function (propagateChange)
* that tells other forn directives and form controls to update
* their values
*/
registerOnChange(fn: any) {
this.propagateChange = fn;
}
/*
* Similar to registerOnChage(), this registers a handler
* specifically for when a control receives a touch event
*/
registerOnTouched(fn: any) {
console.log('onTouched()');
}
setDisabledState(isDisabled: boolean) {
}
}
<input class="formatted-input" [hidden]="textVisible" type="text" (focus)="toggleActive()" value="{{_stringValue}}"/>
<input class="formatted-input" [hidden]="!textVisible" type="number" (change)="setValue($event)" (blur)="toggleActive()"/>
好的,我有点奇怪。我为工作中的项目构建了一个自定义表单控件,该控件基本上包含两个输入。其中之一是数字输入,其隐藏直到用户单击输入。另一个是文本输入,用于以逗号显示数字。一切工作正常,只是当用户单击组件时,他们必须单击两次以获取数字输入以获得焦点。我该如何解决这个问题,请让我知道是否可以澄清这个问题,因为我知道这是一种奇怪的情况
答案 0 :(得分:0)
您可以查看this stackblitz。该演示使用了简化的代码版本,没有实现ControlValueAccessor
。您会注意到,我对stringValue
应用了一种怪异的格式,以清楚显示哪个输入字段是活动的,并且我颠倒了标记中textVisible
的含义。
主要变化如下:
value
属性绑定到numberValue
#numberInput
focusInput
事件处理程序中的(focus)
函数ChangeDetectorRef.detectChanges
标记
<input [hidden]="!textVisible" type="text" value="{{stringValue}}"
(focus)="toggleActive(); focusInput(numberInput)"/>
<input #numberInput [hidden]="textVisible" type="number" [value]="numberValue"
(change)="setValue($event)" (blur)="toggleActive()"/>
代码(简化版)
textVisible = true;
numberValue = 7248;
constructor(private cd: ChangeDetectorRef) { }
toggleActive() {
this.textVisible = !this.textVisible;
}
get stringValue(): string {
return this.numberValue.toLocaleString();
}
setValue(event: Event) {
this.numberValue = parseInt((event.target as HTMLInputElement).value, 10);
}
focusInput(input: HTMLInputElement) {
this.cd.detectChanges();
input.focus();
}