【问题标题】:Unable to set 2 decimal places while calling directive调用指令时无法设置 2 位小数
【发布时间】:2018-07-04 23:03:04
【问题描述】:

我正在尝试编写一个包含管道的指令,该管道将数字除以 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;
  }
}

【问题讨论】:

    标签: angular


    【解决方案1】:

    这是因为你在这里覆盖了decimals 的值:

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

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

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

    在 HTML 中你也可以像这样传递decimals

    shortNumberFormat="shortNumberNoSymbol:.2"
    

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

    【讨论】:

      猜你喜欢
      • 2017-05-29
      • 2019-03-23
      • 1970-01-01
      • 2020-06-07
      • 2021-12-17
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      相关资源
      最近更新 更多