【发布时间】:2018-09-26 02:19:56
【问题描述】:
我有一个自定义的 ControlValueAccessor,它只是在输入上附加一个货币符号。
@Component({
selector: 'app-currency-input',
templateUrl: './currency-input.component.html',
styleUrls: ['./currency-input.component.scss'],
providers: [
CurrencyPipe,
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CurrencyInputComponent),
multi: true
}
]
})
export class CurrencyInputComponent implements ControlValueAccessor {
@Input() class = '';
currencyValue: string;
onChange: (value: number) => void;
onTouched: () => void;
constructor(
private currencyPipe: CurrencyPipe
) { }
parseToNumber(currencyString: string) {
this.onChange(this.currencyPipe.parse(currencyString));
}
transformToCurrencyString(value: number): string {
return this.currencyPipe.transform(value);
}
writeValue(value: number): void {
if (value !== undefined) {
this.currencyValue = this.transformToCurrencyString(value);
}
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
}
CurrencyPipe 只是将字符串解析为数字并将数字转换为货币字符串(带有本地化的十进制分隔符和货币符号)。
当我尝试像这样使用 ReactiveForms 时:
<app-currency-input
name="amount"
class="value-box"
formControlName="amount"
required
></app-currency-input>
...然后手动输入不会触发onChange()。
我有一个解决方法,我订阅控件的valueChanges,然后做一个
control.patchValue(newValue, { emitModelToViewChange: true })
... 成功触发 ControlValueAccessor 的 onChange。 (不带选项的patchValue 也会这样做,因为true 是此选项的默认值。我只是想在这里指出罪魁祸首。)
但我很想使用一个内置解决方案,该解决方案无法解决额外需要的检查和至少两个 valueChanges。
一个简化的 Plunker 试用:https://embed.plnkr.co/c4YMw87FiZMpN5Gr8w1f/
请参阅src/app.ts 中注释掉的代码。
【问题讨论】:
-
onChange: (value: number) => console.log("value change")没有被调用? -
请发帖
./currency-input.component.html -
什么是
?理想情况下,您只想在此处使用普通表单字段。传统上,除非您已导入库,否则您只能在普通表单字段上使用 formControlName。 -
@ForestG 正确,除非我执行提到的解决方法,否则它不会被调用。
标签: angular angular5 onchange angular-reactive-forms controlvalueaccessor