Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将数字变量绑定到角度域中的屏蔽输入_Javascript_Angular - Fatal编程技术网

Javascript 将数字变量绑定到角度域中的屏蔽输入

Javascript 将数字变量绑定到角度域中的屏蔽输入,javascript,angular,Javascript,Angular,现在,我的API上的JSON解析要求我的属性必须严格类型化(即int需要从javascript以数字形式发送,而不是试图解析字符串),我们的输入框上的掩码遇到了问题 特别是,我们的货币掩码将绑定变量更改为字符串,而不是将它们保留为数字 是否可以将数字绑定到输入框,让该输入框显示非数字字符,如$,并严格将数字作为数字键入?我尝试在getter上强制使用parseFloat(),但这并没有影响绑定变量的类型 HTML: 遮罩: import{Directive,ElementRef,HostLi

现在,我的API上的JSON解析要求我的属性必须严格类型化(即int需要从javascript以数字形式发送,而不是试图解析字符串),我们的输入框上的掩码遇到了问题

特别是,我们的货币掩码将绑定变量更改为字符串,而不是将它们保留为数字

是否可以将数字绑定到输入框,让该输入框显示非数字字符,如$,并严格将数字作为数字键入?我尝试在getter上强制使用parseFloat(),但这并没有影响绑定变量的类型

HTML:


遮罩:

import{Directive,ElementRef,HostListener,AfterViewInit,Input,forwardRef,Renderer2}来自“@angular/core”;
从“@angular/forms”导入{NG_VALUE_访问器,ControlValueAccessor};
常量noop=()=>{};
导出常量自定义\输入\控制\值\访问器:任意={
提供:NG_值访问器,
useExisting:forwardRef(()=>CurrencyMaskDirective),
多:真的
};
@指示({
选择器:“[appCurrencyMask]”,
提供者:[自定义\输入\控制\值\访问器]
})
导出类CurrencyMaskDirective在ViewInit、ControlValueAccessor之后实现{
私有el:HTMLInputElement;
//跟踪值而不设置格式
私人内在价值:任何;
私有前缀:字符串;
私有小数分隔符:字符串;
私人千人助手:字符串;
//允许负数交互的可选参数
@输入('allowNegative')
allowNegative:布尔型;
构造函数(private-elementRef:elementRef,private-renderer:render2){
this.el=elementRef.nativeElement;
this.prefix='$';
this.decimalSeparator=';
this.thousandsSeparator=',';
}
//稍后提供的回调的占位符d
//通过控制值访问器
私有onTouchedCallback:()=>void=noop;
私有onChangeCallback:(a:any)=>void=noop;
//集吸气剂
获取值():任意{
返回parseFloat(this.innerValue.toString());
}
//设置访问器,包括调用onchange回调
设定值(v:任意){
如果(v!==此.innerValue){
this.innerValue=v;
这是一个错误(v);
}
}
//从ControlValueAccessor接口
writeValue(值:任意){
if(值!==此.innerValue){
this.el.value=this.transform(value,this.allowNegative);
如果(值){
this.renderer.setAttribute(this.elementRef.nativeElement,'value',value);
}
this.innerValue=parseFloat(值?.toString());
}
}
//从ControlValueAccessor接口
注册变更(fn:任何){
this.onChangeCallback=fn;
}
//从ControlValueAccessor接口
注册人(fn:任何){
this.onTouchedCallback=fn;
}
ngAfterViewInit(){
this.el.style.textAlign='right';
}
//在焦点上删除所有非数字或十进制分隔符值
@HostListener('focus',['$event.target.value']))
onfocus(值){
this.el.value=this.parse(value,this.allowNegative);
如果(该值==“0”){
this.el.value=“”;
}
}
//在蓝色上删除除最后一个符号外的所有符号,并设置为货币格式
@HostListener('blur',['$event.target.value']))
onBlur(值){
这个.ontouchdcallback();
this.el.value=this.transform(value,this.allowNegative);
this.innerValue=this.parse(this.el.value,this.allowNegative);
this.onChangeCallback(this.innerValue);
if(this.innerValue){
this.renderer.setAttribute(this.elementRef.nativeElement,'value',this.innerValue);
}
}
//更改时删除除last.之外的所有符号,并设置为货币格式
@HostListener('change',['$event.target.value']))
onChange(值){
this.el.value=this.transform(value,this.allowNegative);
this.innerValue=this.parse(this.el.value,this.allowNegative);
this.onChangeCallback(this.innerValue);
if(this.innerValue){
this.renderer.setAttribute(this.elementRef.nativeElement,'value',this.innerValue);
}
}
//禁止用户输入除数字和小数分隔符以外的任何内容
@HostListener('keypress',['$event']))
onKeyPress(事件){
const key=event.which | | event.keyCode | 0;
if(key==45&&!this.allowNegative){
event.preventDefault();
}else if(key==45&&this.allowNegative){
//允许负数
}否则,如果(键!==46&&key>31&&key<48 | | key>57)){
event.preventDefault();
}
}
转换(值:string,allowNegative=false,decimalPrecision:number=2){
如果(值==未定义| |值==''){
返回“$0.00”;
}
if(allowNegative){
value=value.toString();
if(value.startsWith(“(”)| | value.startsWith(“-”){
value='-'+value.substr(1,value.length).replace(/\(\\)\$\\-/g');
}否则{
值=值。替换(/\(\\)\$\-/g',);
}
}
让[integer,fraction='']=(value | |'''..toString().split(this.decimalSeparator);
分数=小数精度>0?此.decimalSeparator+(分数+'000000')。子字符串(0,2):“”;
如果(integer.indexOf(',')<0){//1000个参数尚未添加
如果(!isNaN(parseInt(整数))){
integer=parseInt(integer).toString();//删除前导0
}
}
integer=integer.replace(/\B(?=(\d{3})+(?!\d))/g,这个.thousandsSeparator);
//如果用户输入.xx,我们可以显示0.xx
如果(整数==''){
我
<input appCurrencyMask [(ngModel)]="_variable" />
                        
import { Directive, ElementRef, HostListener, AfterViewInit, Input, forwardRef, Renderer2 } from '@angular/core';

import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

const noop = () => { };

export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => CurrencyMaskDirective),
    multi: true
};

@Directive({
    selector: '[appCurrencyMask]',
    providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CurrencyMaskDirective implements AfterViewInit, ControlValueAccessor {
    private el: HTMLInputElement;
    // Keeps track of the value without formatting
    private innerValue: any;
    private prefix: string;
    private decimalSeparator: string;
    private thousandsSeparator: string;
    // Optional Parameter to allow for negative number interaction
    @Input('allowNegative')
    allowNegative: boolean;
    constructor(private elementRef: ElementRef, private renderer: Renderer2) {
        this.el = elementRef.nativeElement;
        this.prefix = '$';
        this.decimalSeparator = '.';
        this.thousandsSeparator = ',';
    }

    // Placeholders for the callbacks which are later providesd
    // by the Control Value Accessor
    private onTouchedCallback: () => void = noop;
    private onChangeCallback: (a: any) => void = noop;

    // set getter
    get value(): any {
        return parseFloat(this.innerValue.toString());
    }

    // set accessor including call the onchange callback
    set value(v: any) {
        if (v !== this.innerValue) {
            this.innerValue = v;
            this.onChangeCallback(v);
        }
    }

    // From ControlValueAccessor interface
    writeValue(value: any) {
        if (value !== this.innerValue) {
            this.el.value = this.transform(value, this.allowNegative);
            if (value) {
                this.renderer.setAttribute(this.elementRef.nativeElement, 'value', value);
            }
            this.innerValue = parseFloat(value?.toString());
        }
    }

    // From ControlValueAccessor interface
    registerOnChange(fn: any) {
        this.onChangeCallback = fn;
    }

    // From ControlValueAccessor interface
    registerOnTouched(fn: any) {
        this.onTouchedCallback = fn;
    }

    ngAfterViewInit() {
        this.el.style.textAlign = 'right';
    }

    // On Focus remove all non-digit or decimal separator values
    @HostListener('focus', ['$event.target.value'])
    onfocus(value) {
        this.el.value = this.parse(value, this.allowNegative);
        if (this.el.value == "0") {
            this.el.value = "";
        }
    }

    // On Blue remove all symbols except last . and set to currency format
    @HostListener('blur', ['$event.target.value'])
    onBlur(value) {
        this.onTouchedCallback();
        this.el.value = this.transform(value, this.allowNegative);
        this.innerValue = this.parse(this.el.value, this.allowNegative);
        this.onChangeCallback(this.innerValue);
        if (this.innerValue) {
            this.renderer.setAttribute(this.elementRef.nativeElement, 'value', this.innerValue);
        }
    }

    // On Change remove all symbols except last . and set to currency format
    @HostListener('change', ['$event.target.value'])
    onChange(value) {
        this.el.value = this.transform(value, this.allowNegative);
        this.innerValue = this.parse(this.el.value, this.allowNegative);
        this.onChangeCallback(this.innerValue);
        if (this.innerValue) {
            this.renderer.setAttribute(this.elementRef.nativeElement, 'value', this.innerValue);
        }
    }

    // Prevent user to enter anything but digits and decimal separator
    @HostListener('keypress', ['$event'])
    onKeyPress(event) {
        const key = event.which || event.keyCode || 0;
        if (key === 45 && !this.allowNegative) {
            event.preventDefault();
        } else if (key === 45 && this.allowNegative) {
            // allow negative numbers
        } else if (key !== 46 && key > 31 && (key < 48 || key > 57)) {
            event.preventDefault();
        }
    }

    transform(value: string, allowNegative = false, decimalPrecision: number = 2) {
        if (value == undefined || value === '') {
            return "$0.00";
        }
        if (allowNegative) {
            value = value.toString();
            if (value.startsWith('(') || value.startsWith('-')) {
                value = '-' + value.substr(1, value.length).replace(/\(|\)|\$|\-/g, '');
            } else {
                value = value.replace(/\(|\)|\$|\-/g, '');
            }
        }
        let [integer, fraction = ''] = (value || '').toString().split(this.decimalSeparator);
        fraction = decimalPrecision > 0 ? this.decimalSeparator + (fraction + '000000').substring(0, 2) : '';
        if (integer.indexOf(',') < 0) { //thousandsSeparators have not been added yet
            if (!isNaN(parseInt(integer))) {
                integer = parseInt(integer).toString(); //remove leading 0s
            }
        }
        integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandsSeparator);

        // If user types .xx we can display 0.xx
        if (integer === '') {
            integer = '0';
        } else if (integer.startsWith('$')) {
            // If there are multiple transforms, remove the previous dollar sign (blur and change at the same time)
            integer = integer.substr(1, integer.length);
        } else if (allowNegative && integer.startsWith('-')) {
            // If user inputs negative number set to paranthesis format
            integer = integer.substr(1, integer.length);
            return '(' + this.prefix + integer + fraction + ')';
        }
        return this.prefix + integer + fraction;
    }

    parse(value: string, allowNegative = false) {
        let [integer, fraction = ''] = (value || '').split(this.decimalSeparator);
        integer = integer.replace(new RegExp(/[^\d\.]/, 'g'), '');
        fraction = parseInt(fraction, 10) > 0 && 2 > 0 ? this.decimalSeparator + (fraction + '000000').substring(0, 2) : '';
        if (allowNegative && value.startsWith('(') && value.endsWith(')')) {
            return (-1 * parseFloat(integer + fraction)).toString();
        } else {
            return integer + fraction;
        }
    }
}
parse(value)