如何从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;
}
}