调用指令时无法设置2个小数位

时间:2018-07-04 23:03:04

标签: angular

我正在尝试编写一个包含管道的指令,该管道会将数字除以1000,并在angular 4应用程序中添加两个小数位。如果直接调用管道,则当您提供2个小数位时可以使用。使用指令时如何指定 请注意,我正在尝试为shortNumberNoSymbol设置十进制值。目前,设置shortNumberFormat =“ shortNumberNoSymbol:.2没什么区别。

使用指令的HTML

<td colspan="2" *ngIf="last" class="text-right">
                <span class="greater-sign"></span>
                <click-input [classNames]="{'has-warning': !isMinValid(item,index), 'number' : true }">
                  <input [(ngModel)]="item.minSize" required min="0" [max]="maxCurrency" shortNumberFormat="shortNumberNoSymbol:.2">
                </click-input>
              </td>

shortNumberFormat指令

import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { Input, Directive, forwardRef, Renderer, ElementRef, PipeTransform, ExistingProvider } from '@angular/core';
import { ShortNumberFormatPipe } from '../pipes/shortNumberFormat/shortNumberFormat.pipe';
import { ShortNumberNoSymbolPipe } from '../pipes/ShortNumberNoSymbol/ShortNumberNoSymbol.pipe';

const CUSTOM_VALUE_ACCESSOR: ExistingProvider = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ShortNumberFormatDirective), multi: true };



@Directive({
    selector: 'input[shortNumberFormat]',
    host: { '(blur)': 'blurred($event.target.value)' },
    providers: [CUSTOM_VALUE_ACCESSOR]
})
export class ShortNumberFormatDirective implements ControlValueAccessor {
    @Input('type') inputType: string;
    @Input('shortNumberFormat') format: string;


    private _parsedFormat: {
        pipe: {
            instance: PipeTransform,
            map?: (x: number) => number
        },
        numbers: {
            minimumIntegerDigits: number,
            minimumFractionDigits: number,
            maximumFractionDigits: number
        },
        raw: string;
    };

    constructor(private _renderer: Renderer, private _elementRef: ElementRef) { }

    onChange = (_: any) => { };
    onTouched = (_: any) => { };
    blurred(value: any) {
        this.onChange(value);
        this.onTouched(value);
    }

    formatToString(value: number): string {
        if (!this._parsedFormat) this.parseFormat();
        const pipe = this._parsedFormat.pipe;
        return pipe.instance.transform(value, this._parsedFormat.raw);
    }

    parseToNumber(value: number): number {
        this.writeValue(value);
        return value;

    }

    writeValue(value: number): void {
        if (this.inputType === 'number') {
            this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', value);
        } else {
            const text = this.formatToString(value);
            this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', text);
        }
    }

    registerOnChange(fn: (_: number) => void): void {
        this.onChange = (value) => { fn(value === '' ? null : this.parseToNumber(value)); };
    }
    registerOnTouched(fn: (_: number) => void): void {
        this.onTouched = (value) => { fn(value === '' ? null : this.parseToNumber(value)); };
        this.inputType = 'number';
    }



    private parseFormat() {
        if (!this.format) throw new Error(`format string not set`);
        const split = this.format.split(':');
        const getPipe = (input: string): {
            instance: PipeTransform,
            map?: (x: number) => number
        } => {

            if (input === 'shortNumberFormat') return { instance: new ShortNumberFormatPipe() };
            if (input === 'shortNumberNoSymbol') return { instance: new ShortNumberNoSymbolPipe() };
            throw new Error(`unknown formatter pipe: ${input}`);
        };
        let minInt = 1, minFraction = 0, maxFraction = 3;
        const digits = split[1];
        this._parsedFormat = {
            pipe: getPipe(split[0]), numbers: {
                minimumIntegerDigits: minInt,
                minimumFractionDigits: minFraction,
                maximumFractionDigits: maxFraction,
            }, raw: digits
        };
    }
}

shortNumberNoSymbol管道

import { Pipe, PipeTransform } from '@angular/core';


@Pipe({
  name: 'shortNumberNoSymbol'
})


export class ShortNumberNoSymbolPipe implements PipeTransform {

  transform(number: any, decimals = 0) {

    if (number === null) {
      return;
    }

    number = parseFloat(number);

    if (isNaN(number)) {
      return;
    }

    if (isNaN(decimals)) {
      return;
    }

    const signPrefix = number < 0 ? '-' : '';
    number = Math.abs(number);

    if (number <= 999) { // hundreds
      number = number.toFixed(decimals);
    } else if (number >= 1000) {  // thousands
      number = (number / 1000).toFixed(decimals);
    } 
    return signPrefix + number;
  }
}

1 个答案:

答案 0 :(得分:0)

这是因为您在此处覆盖了decimals的值:

transform(number: any, decimals = 0) { ... }

,这样每次值将等于0都没关系,您将传递给管道什么。只需删除此重新分配,您就可以使用实际传递的参数:

transform(number: any, decimals: number) { ... }

在HTML中,您也像这样传递decimals

shortNumberFormat="shortNumberNoSymbol:.2"

请注意,这里有多余的点,toFixed()需要整数作为参数。