昨天我试图将一个我必须在 React 中解决的问题翻译成 Svelte,但我无法弄清楚。
问题如下:
- 我有 3 个输入,每个输入都有一个百分比。
- 这 3 个百分比的总和不能超过 100。
- 我有第四个输入,它被禁用了,所以它只显示剩余的百分比到 100%
在 react 中相当容易,声明一个接受的函数、事件和一个变量,以了解我从哪个输入中获取事件。进行适当的验证并完成。
可悲的是,我几乎没有经验,我不知道如何解决它。 到目前为止,这是代码(剧透警告它甚至没有接近做应该做的事情(。 斯维尔特·雷普尔
运行控制台.log以显示 sp1 的值,在验证它的函数内部和函数外部(函数之前和之后(,显示我所期望的:
- 在函数之前(之前(:输入中的值
- 函数内部:值已验证
- 函数外部(之后(:值已验证
因此,正确值的验证和分配发生了,但输入仍然显示错误的值(例如:输入显示 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;
}
}