在Svelte输入组件中处理欧洲十进制格式:同步和解析sssues

问题描述 投票:0回答:1

我正在用 Svelte 编写一个输入组件。我遇到了一个问题。我的应用程序面向欧洲市场。在欧洲,我们使用逗号作为小数点分隔符。

问题是,如果用户在输入中输入欧洲格式的数字(例如 12,5),Javascript 会将其作为字符串接收,并且无法对其执行数学运算。

因此,我为这个问题编写了一个解决方法 - 向用户显示他们在输入 (12,5) 中输入的内容,并且绑定了格式化值 (12.5)。但问题是,如果父级更新输入值,它与显示值不同步。例如,当父项将

value
设置为
""
时,更改在输入中将不可见。

<script>
    export let value;
    export let type = 'text';

    let displayValue = value;
    
    const handleInput = (e) => {
        if (type === 'number') {
            value = formatInputNumber(e.target.value);
            displayValue = e.target.value;
        } else {
            value = e.target.value;
            displayValue = e.target.value;
        }
    };
</script>

<input
    {type}
    value={displayValue}
    on:input={handleInput}
    pattern={type === 'number' ? '[0-9]+([,.][0-9]+)?' : ''}
    {...$$restProps}
/>

一个实际工作示例:https://svelte.dev/repl/4f10a5ed9e164d4c969d61c8fd154ede?version=4.2.9

目前,作为一种解决方法,每次对输入值进行数学运算时,我都会使用

formatInputNumber
函数。然而,这是一种不切实际的方法——我的应用程序主要依赖于数学运算,并且有很多这样的输入。很容易不小心忘记使用这个函数,这样的符号看起来很难看。

javascript input formatting svelte sveltekit
1个回答
0
投票

您可以创建文本和数字输入对,向用户显示文本输入并隐藏数字输入,因此当您对文本应用更改时,它将应用于数字字段,模拟浏览器的操作方式工作,除了逗号和点的差异,当写回数字输入时,您可以随意改变它们。因此,文本将是表示形式,您显示的值和数字字段将是您可用于逻辑和内部计算的字段。因此,您将表示与逻辑分开:

function txttonum(txt, num) {
    num.value = txt.value.replace(",", ".");
    txt.value = num.value.replace(".", ",");
}

for (let context of document.querySelectorAll(".numberfields")) {
    let txt = context.querySelector("input[type=text]");
    let num = context.querySelector("input[type=number]");
    txt.addEventListener("input", function() {
        if (txt.value.indexOf(".") !== txt.value.length - 1) {
            txttonum(txt, num);
        }
    });
}
div.numberfields input[type=number] {
    display: none;
}
<div class="numberfields">
    <input type="text">
    <input type="number">
</div>

<div class="numberfields">
    <input type="text">
    <input type="number">
</div>

<div class="numberfields">
    <input type="text">
    <input type="number">
</div>

© www.soinside.com 2019 - 2024. All rights reserved.