如何从Angular 4中的Ionic 3中的ngModel中单独设置输入值

问题描述:

我有一个指令,我正在创建一个离子3应用程序中的货币输入。我基本想要的是输入$ 11.11,但将ngModel值设置为11.11。如何从Angular 4中的Ionic 3中的ngModel中单独设置输入值

我的模型值设置正确,我的格式化字符串值是正确的,但我无法得到我的输入显示格式化的值。实际上,我的输入会显示我输入的任何内容,字母和标点符号,但所有记录的值都是正确的。有人知道我错过了什么,或者有什么更好的方法去实现我想要实现的目标?


文本输入到输入:1111
ngModel值:11.11
的console.log输入值:$ 11.11
实际输入值:1111(应该是$ 11.11)

import {Directive, Attribute, Output, EventEmitter, ElementRef, Renderer2} from '@angular/core'; 
import { NgModel } from '@angular/forms'; 
import {CurrencyPipe} from "@angular/common"; 

/** 
* Generated class for the CurrencyInputDirective directive. 
* 
* See https://angular.io/docs/ts/latest/api/core/index/DirectiveMetadata-class.html 
* for more info on Angular Directives. 
*/ 
@Directive({ 
    selector: '[currency-input]', 
    providers: [NgModel] 
}) 
export class CurrencyInputDirective { 

    maximumAmount: number; 
    currencyCode: string; 
    decimals: number; 
    modelValue: number; 

    @Output() ciExceededMax: EventEmitter<any> = new EventEmitter(); 

    constructor(public model: NgModel, 
       public elementRef: ElementRef, 
       private currencyPipe: CurrencyPipe, 
       private renderer: Renderer2, 
       @Attribute("ci-maximum-amount") maximumAmount: number, 
       @Attribute("ci-currency-code") currencyCode: string, 
       @Attribute("ci-decimals") decimals: number) { 

    this.maximumAmount = (maximumAmount) ? maximumAmount : 10000; 
    this.currencyCode = (currencyCode) ? currencyCode: 'USD'; 
    this.decimals = (decimals) ? Math.trunc(decimals) : 2; 

    let directive = this; 
    this.model.valueChanges.subscribe(function (value) { 
     directive.modelValue = directive.getModelValue(value); 
     directive.model.viewToModelUpdate(directive.modelValue); 
     directive.writeValueToInput(directive.getFormattedModelValue(directive.modelValue)); 
    }); 

    } 

    writeValueToInput(value) { 

    //this.elementRef.nativeElement.value = value; 
    this.renderer.setProperty(this.elementRef.nativeElement, 'value', value); 

    console.log("element ref value " + this.elementRef.nativeElement.value); 
    console.log("element ref " + JSON.stringify(this.elementRef.nativeElement, undefined, 2)); 
    } 

    getFormattedModelValue(value) { 
    let currencyDecimals = '1.' + this.decimals + "-" + this.decimals; 

    let retVal: string = (!value) ? null : this.currencyPipe.transform(value, this.currencyCode, true, currencyDecimals); 
    return (retVal) ? retVal : this.currencyPipe.transform(0, this.currencyCode, true, currencyDecimals); 
    } 

    getModelValue(value) { 

    if(!value) 
     return 0; 

    let strippedValue: string = value.replace(/[^0-9]/g,""); 
    let parsedInt: number = parseInt(strippedValue); 
    let calculatedAmount = (parsedInt/Math.pow(10, this.decimals)); 

    if(calculatedAmount > this.maximumAmount){ 
     calculatedAmount = this.modelValue; 

     setTimeout(() => { 
     this.ciExceededMax.emit({amount: calculatedAmount, maxAmount: this.maximumAmount}); 
     }, 1); 
    } 

    console.log("returning calculated amount " + calculatedAmount); 

    return calculatedAmount; 
    } 

} 

我得到它了。我需要使用NgControl来写入输入值。

import {Directive, Attribute, Output, EventEmitter} from '@angular/core'; 
import {NgModel, NgControl} from '@angular/forms'; 
import {CurrencyPipe} from "@angular/common"; 

/** 
* Generated class for the CurrencyInputDirective directive. 
* 
* See https://angular.io/docs/ts/latest/api/core/index/DirectiveMetadata-class.html 
* for more info on Angular Directives. 
*/ 
@Directive({ 
    selector: '[currency-input]', 
    providers: [NgModel] 
}) 
export class CurrencyInputDirective { 

    maximumAmount: number; 
    currencyCode: string; 
    decimals: number; 
    modelValue: number; 

    @Output() ciExceededMax: EventEmitter<any> = new EventEmitter(); 

    constructor(public model: NgModel, 
       private control : NgControl, 
       private currencyPipe: CurrencyPipe, 
       @Attribute("ci-maximum-amount") maximumAmount: number, 
       @Attribute("ci-currency-code") currencyCode: string, 
       @Attribute("ci-decimals") decimals: number) { 

    this.maximumAmount = (maximumAmount) ? maximumAmount : 10000; 
    this.currencyCode = (currencyCode) ? currencyCode: 'USD'; 
    this.decimals = (decimals) ? Math.trunc(decimals) : 2; 

    let directive = this; 
    this.model.valueChanges.subscribe(function (value) { 
     directive.modelValue = directive.getModelValue(value); 
     directive.model.viewToModelUpdate(directive.modelValue); 
     directive.control.valueAccessor.writeValue(directive.getFormattedModelValue(directive.modelValue)); 
    }); 

    } 

    getFormattedModelValue(value) { 
    let currencyDecimals = '1.' + this.decimals + "-" + this.decimals; 

    let retVal: string = (!value) ? null : this.currencyPipe.transform(value, this.currencyCode, true, currencyDecimals); 
    return (retVal) ? retVal : this.currencyPipe.transform(0, this.currencyCode, true, currencyDecimals); 
    } 

    getModelValue(value) { 

    if(!value) 
     return 0; 

    let strippedValue: string = value.replace(/[^0-9]/g,""); 
    let parsedInt: number = parseInt(strippedValue); 
    let calculatedAmount = (parsedInt/Math.pow(10, this.decimals)); 

    if(calculatedAmount > this.maximumAmount){ 
     calculatedAmount = this.modelValue; 

     setTimeout(() => { 
     this.ciExceededMax.emit({amount: calculatedAmount, maxAmount: this.maximumAmount}); 
     }, 1); 
    } 

    return calculatedAmount; 
    } 

}