我有一个指令我正在为离子3应用中的货币输入创建。我基本上想要的是一个输入,表示$ 11.11,但将ngModel值设置为11.11。
我的模型值设置正确,格式化的字符串值正确,但我无法获取输入以显示格式化的值。实际上,我的输入显示我输入的任何内容,字母和标点符号,但所有记录的值都是正确的。有谁知道我错过了什么或更好的方式来实现我想要实现的目标?
示例
输入的文字输入: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;
}
}
答案 0 :(得分:0)
我明白了。我需要使用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;
}
}