Svelte3 输入验证
Svelte3 input validation
昨天我试图将我必须在 React 中解决的问题转换为 Svelte,但我无法弄明白。
问题如下:
- 我有 3 个输入,每个输入都有一个百分比。
- 3个百分比加起来不能超过100
- 我有第四个输入,它被禁用了,所以它只显示剩余百分比为 100%
在 React 中相当简单,声明一个接受事件的函数和一个变量,以了解我从哪个输入获取事件。进行适当的验证并完成。
可悲的是,我的经验几乎为0,而且我不知道如何解决。
这是到目前为止的代码(剧透警告它甚至没有接近做应该做的事情)。
Svelte REPL
运行 a console.log 显示 sp1 的值,在验证它的函数内部和函数外部(函数前后),显示我所期望的:
- 函数前(before):输入中的值
- 函数内部:值已验证
- 函数外(之后):值已验证
所以正确值的验证和分配发生了,尽管如此,输入仍然显示错误的值(例如:输入显示 112,该值应该是 100)。
一种更动态的方法是使用数组。
let inputs = [{
value: 0,
color: 'GRAY'
}, {
value: 0,
color: 'DARKSLATEGRAY'
}, {
value: 0,
color: 'TEAL'
}];
这也将使计算更容易,因为我们可以使用数组方法。它还将使我们能够使用 each
块来删除冗余代码。然后我们将使用一个名为 validate
的函数并将当前输入的索引传递给它。使用 input
我们可以计算可以在 input
中输入的最大可能值,如果超过该最大值则设置 input
。此 validate
函数将在 input
事件中从模板调用。
这是代码。
<script>
let total = 100;
let inputs = [{
value: 0,
color: 'GRAY'
}, {
value: 0,
color: 'DARKSLATEGRAY'
}, {
value: 0,
color: 'TEAL'
}];
$: spOthers = total - inputs.map(x => x.value || 0).reduce((a, b) => a + b);
function validate(index) {
let maxInput = total - inputs.map(x => x.value).filter((x, i) => i !== index).reduce((a, b) => a + b);
if (inputs[index].value > maxInput) {
inputs[index].value = maxInput;
}
}
</script>
{#each inputs as {value, color}, i}
<div class='input-container'>
<div class='square' style="background-color: {color}" />
<input type="number" min="0" class='input' bind:value={value} on:input={() => validate(i)} />
</div>
{/each}
<div class='input-container'>
<div class='square' style="background-color: DARKORANGE" />
<input type='number' class='input input-others' bind:value={spOthers} disabled/>
</div>
注意:上面的样式我已经省略了,因为它们没有变化。
这是工作 REPL。
不错。您还可以:
$: spOthers = inputs.reduce((a, c, i, inputs) => a + c.value, 0);
function validate(index) {
const delta = spOthers - total;
if (delta > 0) {
inputs[index].value -= delta;
}
}
昨天我试图将我必须在 React 中解决的问题转换为 Svelte,但我无法弄明白。
问题如下:
- 我有 3 个输入,每个输入都有一个百分比。
- 3个百分比加起来不能超过100
- 我有第四个输入,它被禁用了,所以它只显示剩余百分比为 100%
在 React 中相当简单,声明一个接受事件的函数和一个变量,以了解我从哪个输入获取事件。进行适当的验证并完成。
可悲的是,我的经验几乎为0,而且我不知道如何解决。 这是到目前为止的代码(剧透警告它甚至没有接近做应该做的事情)。 Svelte REPL
运行 a console.log 显示 sp1 的值,在验证它的函数内部和函数外部(函数前后),显示我所期望的:
- 函数前(before):输入中的值
- 函数内部:值已验证
- 函数外(之后):值已验证
所以正确值的验证和分配发生了,尽管如此,输入仍然显示错误的值(例如:输入显示 112,该值应该是 100)。
一种更动态的方法是使用数组。
let inputs = [{
value: 0,
color: 'GRAY'
}, {
value: 0,
color: 'DARKSLATEGRAY'
}, {
value: 0,
color: 'TEAL'
}];
这也将使计算更容易,因为我们可以使用数组方法。它还将使我们能够使用 each
块来删除冗余代码。然后我们将使用一个名为 validate
的函数并将当前输入的索引传递给它。使用 input
我们可以计算可以在 input
中输入的最大可能值,如果超过该最大值则设置 input
。此 validate
函数将在 input
事件中从模板调用。
这是代码。
<script>
let total = 100;
let inputs = [{
value: 0,
color: 'GRAY'
}, {
value: 0,
color: 'DARKSLATEGRAY'
}, {
value: 0,
color: 'TEAL'
}];
$: spOthers = total - inputs.map(x => x.value || 0).reduce((a, b) => a + b);
function validate(index) {
let maxInput = total - inputs.map(x => x.value).filter((x, i) => i !== index).reduce((a, b) => a + b);
if (inputs[index].value > maxInput) {
inputs[index].value = maxInput;
}
}
</script>
{#each inputs as {value, color}, i}
<div class='input-container'>
<div class='square' style="background-color: {color}" />
<input type="number" min="0" class='input' bind:value={value} on:input={() => validate(i)} />
</div>
{/each}
<div class='input-container'>
<div class='square' style="background-color: DARKORANGE" />
<input type='number' class='input input-others' bind:value={spOthers} disabled/>
</div>
注意:上面的样式我已经省略了,因为它们没有变化。
这是工作 REPL。
不错。您还可以:
$: spOthers = inputs.reduce((a, c, i, inputs) => a + c.value, 0);
function validate(index) {
const delta = spOthers - total;
if (delta > 0) {
inputs[index].value -= delta;
}
}