【问题标题】:How do I set an input's value separately from the ngModel in Ionic 3 with Angular 4如何使用 Angular 4 在 Ionic 3 中将输入值与 ngModel 分开设置
【发布时间】:2018-02-06 02:56:14
【问题描述】:

我正在为 ionic 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;
  }

}

【问题讨论】:

    标签: angular ionic3


    【解决方案1】:

    我明白了。我需要使用 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;
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2018-04-12
      • 2017-11-13
      • 2021-01-26
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 2018-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多