如何将两个指令添加到一个字段

时间:2017-05-10 09:31:18

标签: angular

我有两个指令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) || '';
}

}

1 个答案:

答案 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。