我有两个指令toPercentage
,其中数字乘以100,另一个isRounding
选择.00(十进制)之后的数字,两者都是逐个工作但不是一起工作!
<input type="number" name="name" toPercentage isRounding [ngModel]="val.employerShare" (ngModelChange)="val.employerShare = $event">
这两个指令实现了一个自定义值访问器,当我在输入字段中使用它们时抛出此错误
错误:多个自定义值访问器与_throwError
中未指定名称属性的表单控件匹配
import { Directive, ElementRef, Input, forwardRef, EventEmitter, Renderer } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, NgModel } from "@angular/forms";
@Directive({
selector: '[ngModel][toPercentage]',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ToPercentDirective),
multi: true
}],
host: {
"[value]": 'ngModel',
'(blur)': 'onBlur()'
}
})
export class ToPercentDirective implements ControlValueAccessor {
constructor(private el: ElementRef, private renderer:Renderer) { }
private innerValue: string;
private toNumber: number;
private toPercent:number;
public onChangeCallback : any = (_) => { console.log(_) }
public onTouched: any = () => { /*Empty*/ }
onBlur(){
var input = this.el.nativeElement.value;
this.toPercent = parseFloat(input) / 100;
if(input != this.toNumber){
this.onChangeCallback(this.toPercent);
}
}
writeValue(val: string): void {
// this.ngModel.ControlValueAccessor.writeValue(val);
this.toNumber = parseFloat(val) * 100;
this.el.nativeElement.value = this.toNumber;
}
registerOnChange(fn: any): void {
// console.log(fn);
this.onChangeCallback = fn;
}
registerOnTouched(fn: any): void {
// console.log(fn);
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean) : void{
this.renderer.setElementProperty(this.el.nativeElement, 'disabled', isDisabled);
}
}
import { Directive, ElementRef, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
@Directive({
selector: '[isRounding]',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => IsRoundingDirective),
multi: true
}],
host: {
"[value]": 'ngModel',
'(blur)': 'onBlur()'
}
})
export class IsRoundingDirective implements ControlValueAccessor {
constructor(private el: ElementRef) {
console.log(el.nativeElement.getAttribute('isRounding'));
this.numberPad = el.nativeElement.getAttribute('isRounding') || 2;
}
private numberPad = 2;
isRoundingFlag = localStorage.getItem('isRounding');
public onChangeCallback : any = (_) => { console.log(_) }
onBlur() {
var input = this.el.nativeElement.value;
input = this.roundNumber(input) || null;
this.onChangeCallback(input);
this.el.nativeElement.value = input;
}
writeValue(val: string): void {
if(this.isRoundingFlag === 'true') {
this.el.nativeElement.value = this.roundNumber(val);
}else {
this.el.nativeElement.value = val;
}
}
registerOnChange(fn: any): void {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any): void {
}
roundNumber(val) {
var roundedValue = parseFloat(val);
return roundedValue.toFixed(this.numberPad) || '';
}
}
答案 0 :(得分:0)
我知道这是一个比较老的问题,但是我尝试将“ masking”指令附加到使用NG_VALUE_ACCESSOR的自定义表单控件时遇到了类似的问题,这是我发现唯一与我的问题匹配的stackOverflow问题;所以我要说的是我的解决方案,如果还有其他人也这样做。
经过大量搜索,我发现我们可以使用NgControl访问表单控件对象,然后订阅valueChanges,以便在值更改时得到通知。在这种情况下,我想您可以对舍入或百分比进行更改,并使用patchValue({value})用新更改对其进行更新(当然,您需要注意您的更改不会产生永恒的循环)>
import {
Directive
, OnChanges
, Optional
, Input
, SimpleChanges } from '@angular/core';
import { NgControl } from '@angular/forms';
@Directive({
selector: '[appMyDirective]',
providers: []
})
export class MyDirective implements OnChanges {
@Input()
value: any;
constructor(@Optional() private ngControl: NgControl) {
if (this.ngControl) {
this.ngControl.valueChanges.subscribe((value) => {
// do something with the value change here.
});
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.value) {
// do something with the value here
}
}
}
注意:如果您将指令附加到非格式对象,则我包含ngOnChanges。