2017-05-25 3 views
0

浮動小数点ディレクティブを反応形式のフィールドに追加して、カンマを1000に追加し、フィールド値に.00を追加します。 。角4 valueChangesを使用するのではなく、setValueまたはpatchValueをリッスンします。

  • onBlurイベントがのonFocus、値は以下のように一度フォーマットされたので、私は私の浮動小数点命令にこれを追加して既存の値を持つフォームの負荷が、私はこれらの値をフォーマットすることがしたかった場合

をフォーマット削除

  • をフォーマット追加フォームフィールドはsetValueまたはpatchValueを使用して塗りつぶします。浮動小数点指令

    public ngOnInit() { 
        this.formatFloat(); 
    } 
    
    private formatFloat() { 
        const handle = this.ngControl.valueChanges 
        .subscribe((value: string) => { 
         const float = this.getFloat(); 
         if (float) { 
         this.element.value = this.format(value); 
         } 
         handle.unsubscribe(); 
        }); 
    } 
    

    から

    スニペットは**下記のフルディレクティブを追加しましたが、これは本当に重要部分のみです。

    フォームフィールドをFormArrayに動的に追加して空のフォームを記入すると、1回の書式設定がトリガーされないため、フィールドに入力する最初の桁が書式を追加します。たとえば、空のフォームを開き、ダイナミックフィールドを追加するボタンをクリックし、フィールドに1と入力すると、valueChangeが入力され、入力には1.00が入力され、ユーザーは11244の代わりに1.001244と入力し続けます。

    私はpatchValue知っているとsetValueは直接emitEventdocsを通じてvalueChangesにリンクされているが、代わりにvalueChangesのリスニングのsetValueまたはpatchValue変更をリッスンする方法はありますか?あるいは、これを実現させる別の方法はありますが、ちょうどちょうどsetValuepatchValueを聞いても、1回のフォーマットのサブスクリプションがまだ生き残っていることになるので、既存の機能があります。

    浮動小数点指令

    import { Directive, HostListener, ElementRef, OnInit } from '@angular/core'; 
    import { DecimalPipe } from '@angular/common'; 
    import { FormGroup, NgControl } from '@angular/forms'; 
    
    @Directive({ 
        selector: '[cfFloat]', 
        providers: [DecimalPipe] // TODO: why do I need this? 
    }) 
    export class FloatDirective implements OnInit { 
        public element: HTMLInputElement; 
    
        constructor(
        private elementRef: ElementRef, 
        private decimalPipe: DecimalPipe, 
        private ngControl: NgControl 
    ) { 
        this.element = this.elementRef.nativeElement; 
        } 
    
        @HostListener('blur', ['$event']) 
        onBlur(event: KeyboardEvent) { 
        const float = this.getFloat(); 
        if (float) { 
         this.element.value = this.format(float); 
        } 
        } 
    
        @HostListener('focus', ['$event']) 
        onFocus(event: KeyboardEvent) { 
        const float = this.getFloat(); 
        if (float) { 
         this.element.value = this.replace(float); 
        } 
        } 
    
        public ngOnInit() { 
        this.formatFloat(); 
        } 
    
        private formatFloat() { 
        const handle = this.ngControl.valueChanges 
         .subscribe((value: string) => { 
         const float = this.getFloat(); 
         if (float) { 
          this.element.value = this.format(value); 
         } 
         handle.unsubscribe(); 
         }); 
        } 
    
        private getFloat(): string { 
        const value = this.element.value; 
        const float = this.replace(value); 
        // Only perform an action when a floating point value exists and there are 
        // no errors, otherwise leave the erroneous value to be fixed manually by 
        // ignoring an action 
        if (value && float && this.checkIsValid()) { 
         return float; 
        } 
        } 
    
        private checkIsValid(): boolean { 
        return !this.ngControl.control.errors; 
        } 
    
        private replace(value: string): string { 
        return value.replace(/[^\d\.]+/g, ''); 
        } 
    
        private format(value: string) { 
        return this.decimalPipe.transform(value, '1.2-2'); 
        } 
    
    } 
    
  • 答えて

    0

    さて、これを考え出しました。恐ろしい修正ではありませんが、それはもっとエレガントかもしれないようです。

    private onInitFormatHandler: Subscription; // <-- ADDED HANDLER AS MEMBER VARIABLE INSTEAD 
    
    @HostListener('focus', ['$event']) 
    onFocus(event: KeyboardEvent) { 
    
        // Remove initial formatting subscription since no patch of the value has 
        // occurred, and is no longer likely to occur if the user is actively 
        // applying focus 
        // --- 
        // NOTE: Not unsubscribing causes formatting to occur on dynamically added 
        // fields on the first change of the input value prior to blur 
        if (!this.onInitFormatHandler.closed) { // <-- ADDED CHECK AND EXTRA UNSUBSCRIPTION 
        this.onInitFormatHandler.unsubscribe(); 
        } 
    
        const float = this.getFloat(); 
        if (float) { 
        this.element.value = this.replace(float); 
        } 
    } 
    
    public ngOnInit() { 
        this.formatFloat(); 
    } 
    
    /** 
    * Format the input value only once after the initial form response has 
    * patched the model. 
    * --- 
    * NOTE: Format handler is stored and unsubscribed either on valueChange, or 
    * if focus is applied to the field, whichever occurs first. 
    */ 
    private formatFloat() { 
        this.onInitFormatHandler = this.ngControl.valueChanges // <-- UPDATED HANDLER TO BE MEMBER VARIABLE 
        .subscribe((value: string) => { 
         const float = this.getFloat(); 
         if (float) { 
         this.element.value = this.format(value); 
         } 
         this.onInitFormatHandler.unsubscribe(); // <-- UPDATED HANDLER TO BE MEMBER VARIABLE 
        }); 
    } 
    
    関連する問題